Calendar time zones produce the same bug report over and over. The meeting shows 09:00 for you and 15:00 for the person you invited. Or it was correct for three weeks and then moved by an hour the Monday after the clocks changed. Or the reminder fires while you're asleep.
It's almost never a rendering bug. The event was stored as a bare wall-clock time — "9 o'clock" — with no record of which 9 o'clock, and everything downstream then guessed. The guesses differ, so the answers differ.
This is how calendar time zones actually work, why the failure surfaces weeks after the mistake, and what changes when events carry their own time zones with them.
The Floating-Time Problem
Suppose a calendar stores a start time as 2026-09-14 09:00 and nothing else. That value is ambiguous, and every part of the system is free to interpret it differently.
A browser form submits whatever the user typed. A CalDAV client sends the time along with a zone identifier, and if the server ignores the identifier it stores the wall clock. An export writes the stored value out and marks it UTC, because it has to mark it as something. A reminder compares the stored value against the current time in UTC.
Four components, four interpretations, one number. If everyone involved happens to be in UTC, they agree and everything works. Add one person in Berlin and they diverge — quietly, and only for some events.
The signature of this class of bug is that it's invisible in testing. Developers and users in the same zone never see it. It appears when someone travels, when the clocks change, or when the first person outside your time zone is invited.
Three Kinds of Calendar Time Zones
The iCalendar standard, which every calendar system implements, represents time zones three different ways. Understanding the difference removes most of the confusion.| Kind | Looks like | Means | Right for |
|---|---|---|---|
| UTC | 20260914T070000Z | One exact instant, everywhere | Meetings between people in different places |
| Zoned | TZID=Europe/Berlin:20260914T090000 | 9am in Berlin, converted for everyone else | An event anchored to a physical location |
| Floating | 20260914T090000 | 9am wherever the viewer is | All-day events, birthdays, personal reminders |
Floating time isn't a mistake in itself — it's correct for a birthday, which is on the 14th regardless of where you're standing. It becomes a bug when it's used for a meeting, because a meeting has one instant and floating time has as many instants as it has viewers.
All-day events stay floating on purpose. A public holiday converted to UTC and back can drift into the previous evening for anyone west of Greenwich, which is why the standard represents them as plain dates and why they're never converted.
Daylight Saving Is Where Time Zones Bite
Time zones would be manageable if offsets were constant. They aren't, and the transitions are what turn a latent bug into a support ticket.
Berlin is UTC+1 in winter and UTC+2 in summer. A recurring meeting stored as UTC will drift by an hour relative to the local clock when the transition happens — correct as an instant, wrong as "the 9am standup". A meeting stored as Europe/Berlin plus a wall-clock time stays at 9am through the transition, which is what people expect from a recurring local meeting.
It gets worse across borders, because time zones don't switch on the same day. Europe and North America change a week or two apart, and during that gap the offset between London and New York is one hour different from usual. Every year, for two weeks, transatlantic recurring meetings happen at the wrong time for one side, and every year somebody files a bug about it.
This isn't fixable by picking a better default. It's inherent: "the same instant" and "the same local hour" are different requirements, and a recurring meeting has to choose. Storing the zone alongside the time is what makes the choice representable at all.
Storing UTC Plus the Time Zone
The correct storage model for calendar time zones is both pieces: the exact instant in UTC, and the zone the event was created in.
The instant makes comparison and conversion unambiguous — reminders, sorting and overlap detection all become plain arithmetic. The time zone preserves intent, which is what you need to render an edit form correctly and to round-trip the event back out to a CalDAV client without losing information.
What that changes in practice:
- Creating an event in webmail sends the browser's time zone alongside the time you typed. The server converts to UTC and records that you meant Berlin.
- Viewing it anywhere converts UTC back to the viewer's local time zone. Berlin sees 09:00, San Francisco sees 00:00, and both are right.
- Reminders compare two UTC values, so they fire at the correct moment regardless of where you're.
- Editing shows the original time zone, so changing the description doesn't silently reinterpret the time.
Older Events Keep Their Old Time Zones
Events created before events carried their own time zones have none recorded, and they're left alone — displayed and compared exactly as they always were.
That's deliberate. Retroactively assigning time zones to old events means guessing, and a wrong guess moves appointments in people's calendars without asking. An event that has been showing 14:00 for two years should keep showing 14:00, even if the storage underneath is less precise than it should have been.
The fleet heals itself through ordinary use instead: open an old event, change anything, save, and it's stored zone-aware from then on. Events nobody touches keep their old behaviour, which is the same behaviour they have always had.
If you've a recurring meeting from the old world that has been subtly wrong for people abroad, opening it and re-saving is the fix.
CalDAV, ICS, and Everyone Else's Calendar
A calendar that only worked in one web interface wouldn't be worth much. Apple Calendar, Google Calendar, Thunderbird, and mobile calendar apps all speak CalDAV, and the time-zone contract has to hold across all of them.
When a client writes an event, the zone identifier it sends is used: the time is converted to UTC and the zone is recorded. When a client reads one back, the event is emitted as an exact UTC instant, which every client interprets identically. All-day events pass through as plain dates and are never converted, exactly as the standard requires.
The result is that an event created on an iPhone in Berlin, edited in webmail from a laptop in Lisbon and read in Thunderbird in New York shows the same instant in all three, each rendered in the reader's local time zone. The zone names themselves come from the IANA time zone database.
Setup guides per client: Apple Calendar on macOS, iPhone and iPad, Android with DAVx⁵, and Thunderbird. Outlook needs a third-party plugin for CalDAV; the caveats are in connecting Outlook.
Practices That Prevent Time Zone Bugs
Put the time zone in the title for cross-border meetings. "Weekly sync (09:00 CET)" removes all doubt when someone reads the invite in an email client that renders it badly. Ugly and effective.
Schedule recurring meetings from the time zone that owns them. If the standup is anchored to the Berlin office, create it in Berlin's time zone. The people abroad will see it shift by an hour twice a year, which is correct — the meeting didn't move; their offset did.
Avoid the two weeks around clock changes for anything critical. Europe and North America transition on different dates, and during the gap the usual offset is wrong by an hour. Confirm in writing.
Use all-day events for all-day things. A conference is a date, not an instant. Storing it as a timed event with an arbitrary start hour causes exactly the drift you're trying to avoid.
Re-save old recurring events once. Anything created before events carried their time zones is floating; opening and saving it stores it properly. The same applies to scheduled send, which uses your browser's zone for the delivery time.Frequently Asked Questions
Why does my meeting show a different time in other time zones?
Either the event was stored without a zone, so each side interpreted the wall-clock time locally, or one client is genuinely misconfigured. Re-saving the event from webmail stores it zone-aware and usually resolves it.
Why did my recurring meeting move by an hour?
A daylight-saving transition. An event anchored to an exact instant keeps that instant and appears to move on the local clock; one anchored to a local zone keeps the local hour and appears to move for people elsewhere. Both are correct answers to different questions.
Which time zone is used when I create an event in webmail?
Your browser's, detected automatically. The time is stored as an exact instant with your zone recorded alongside it.
Do all-day events get converted?
No, and they shouldn't be. All-day events are plain dates by the standard. Converting them causes them to drift into the adjacent day for viewers in other zones.
What happens to events created before time zones were stored?
They keep their existing behaviour rather than being retroactively reinterpreted. Open one, save it, and it's stored zone-aware from then on.
Do time zones work correctly with Apple Calendar and Google Calendar?
Yes, over CalDAV. Events are exchanged as exact UTC instants, which every compliant client renders in the viewer's local zone.
Can I set time zones explicitly through the API?
Yes. Event creation and updates accept a time-zone parameter over the REST API and MCP. An automation that omits it's relying on a default rather than stating intent.
Why do reminders fire at the wrong time on old events?
A reminder compares the event time against the current time. If the event has no time zone recorded, that comparison is between a wall-clock value and a real instant, and it's off by your offset. Re-saving the event fixes it.