You open the calendar, see white space, and say yes. Then the day fills with everything that was never in the calendar, and the two hours you promised never happen. The white space was never evidence — it looks identical whether the day is free or whether your calendar simply does not record your life.
Every planner in the category treats a gap as availability. Hodie first asks whether your calendar is worth reading at all: how many of your last 28 days carry any entry. Below half, no arithmetic on today’s gaps means anything, and the app says so rather than drawing you a confident free block.
The count is a proportion read from a finite number of days, so it carries a sampling band, and the band is what decides — not the midpoint. “About half” is reported as undecided, not rounded into a verdict.
| Days with an entry | Share | Band | Verdict |
|---|---|---|---|
| 4 / 28 | 14.3% | ±6.6% | too sparse |
| 10 / 28 | 35.7% | ±9.1% | too sparse |
| 12 / 28 | 42.9% | ±9.4% | undecided |
| 14 / 28 | 50.0% | ±9.4% | undecided |
| 16 / 28 | 57.1% | ±9.4% | undecided |
| 18 / 28 | 64.3% | ±9.1% | readable |
| 24 / 28 | 85.7% | ±6.6% | readable |
Note that 57.1% is still undecided. A majority of days carrying an entry is not the same as a calendar that can be read as a picture of your life, and the difference is exactly the width of the band.
Four scattered twenty-minute gaps are not eighty minutes of work. Hodie gates every answer on the longest single uninterrupted block first, and only then on totals. A day with five meetings and six gaps — 45, 45, 40, 40, 35, 35 minutes — has four hours free and cannot hold ninety minutes of anything. Every planner that answers from the total gets that day wrong.
Today’s committed minutes are compared with the median of your recent days of the same kind — weekday against weekday, weekend against weekend. If today looks emptier than usual, that difference is almost certainly work that exists but was never written down, and it comes off the free time.
The correction runs one way only. A calendar can prove a day is busy; it can never prove a day is free. If today’s calendar shows more than the median, that is a recorded load, not a gift, and nothing is added back.
The median, not the mean: one ten-hour conference day moves a mean and leaves a median where it was. And the spread is measured with median absolute deviation rather than a standard deviation, because in calendar data the outlier days are the rule, and a squared measure builds the band on top of them.
Most estimates are drawn symmetrically around a midpoint. This one cannot be: the ceiling is what the calendar wrote, and nothing can exceed it. Only the floor moves, and it moves with how much your days actually vary.
| How much your days vary | On a bad day | At most | Verdict for 2 h 30 min |
|---|---|---|---|
| ± 0 min | 3 h | 3 h | there is room |
| ± 24 min | 2 h 36 min | 3 h | there is room |
| ± 37 min | 2 h 23 min | 3 h | I can’t tell |
| ± 1 h 38 min | 1 h 22 min | 3 h | I can’t tell |
Same day, same calendar, same three hours of ceiling throughout. Only the floor changes — and with it, whether an answer is available at all.
Yes means it fits even on a bad day. No means it does not fit even on a perfect one. Everything between is I can’t tell, with the reason: the calendar records too few of your days, the coverage sits on the line, there is not enough history to build a band, or the band crosses what you asked for. A planner that never says this is not more useful; it is only more confident.
Raise your arm and get the verdict and a single number. No calendar grid, no lists, no settings squeezed onto forty millimetres. The iPhone did the measuring; the watch says what came out of it.
Free. No in-app purchases, no subscription, no account. iPhone, iPad and Apple Watch. Six languages of interface.
Each claim above corresponds to a check that runs on every build and fails it if the claim stops being true. The source is scanned with comments stripped for URLSession, URLRequest, CFNetwork, NWConnection, CLLocationManager and StoreKit; any file that touches EKEvent is additionally scanned for reads of title, notes, location, url, attendees or organizer, and finding one fails the build. The permission strings that are supposed to be absent are checked for absence, and the one that is supposed to be present is checked for presence. A promise nobody measures is worse than no promise, because people rely on it.
Every figure on this page and in the App Store screenshots comes from the shipping core, run over days built from a written rule — event start-and-duration pairs and a deterministic history pattern — not from a design file. The core carries 45 tests, and a mutation gate breaks each of its 32 defences one at a time to check that a test actually goes red. The asymmetric band was not designed that way: a failing test revealed a symmetric band claiming an upper bound of 400 minutes on a day whose calendar showed only 300, and the structure was rebuilt around what the calendar can and cannot prove.