Store time in an absolute standard; convert to local only at display
Aliases: UTC storage · instant storage · convert at display · naive local time
What it is
An event happens at an instant, and that instant is one thing in the world. Store an absolute standard; convert to local only at display: the store records the instant (commonly Coordinated Universal Time); the screen then draws a clock face in the viewer’s zone. Do not record “15:00”, a local numeral with no affiliation, as the truth. Whether collaboration should also draw the other person’s local is a presentation policy. This is only about which layer is the fact and which layer is the drawing.
Why it happens
A local clock face is a projection. The same instant is 23:00 in Beijing and 16:00 in London: two strings, one fact. Store the local string, and the projection is written down as the fact. The viewer changes zone, the rules change for daylight saving, someone else opens the same record: none of them can recover the instant from “15:00”; they can only guess. An absolute instant (UTC, or a timestamp with an explicit offset) does not depend on who is looking. The presentation layer takes the instant and “this viewer’s zone now” and converts once; the clock face is then for this person.
Writing local and guessing the zone at read time is doing the conversion early and throwing away the input to it. The DST night, a historical rule change, a flight: every guess is wrong. Storing the instant leaves conversion until the beat it is drawn, using the zone of that moment and the rule table of that moment.
Where it stops holding
“Every Tuesday at ten” is not an instant. It is a local clock-face rule. Storing one UTC moment is not enough — on a DST boundary that ten becomes nine. Recurring rules need a zone identifier and a local clock face stored separately; the instant is computed each time the occurrence is expanded. A purely local alarm that will never leave this device (a bedside clock) may store a local clock face, provided the record is guaranteed not to sync. Logs that must line up for audit may keep presenting in UTC; “convert only at display” permits conversion, it does not require a local face for every viewer.
Applying it
- Events that happened, messages, orders, audit points: store an absolute instant; draw a clock face in the viewer’s zone at presentation.
- Do not write the server machine’s local zone into the store as a default, and do not store offset-less naive local time as the truth.
- Input may collect a local clock face; on the way in, convert with the zone then chosen, and store the instant.
- How to check: open the same record in two zones; clock faces should differ, the instant they name should not. Change the stored field to an unzoned “15:00”, open after a zone change; it should be impossible to prove it is still the same instant. A bedside alarm may store local; a calendar that syncs across devices may not.
Related
- Same group: I4.08.2 Recurring events that cross DST must recompute local clock time, not a fixed offset · I4.08.3 Time-zone rules change with politics; year-spanning conversion cannot assume a frozen map · I4.08.4 After the user changes zone, past records must keep the same absolute instant
- Nearby: I4.05 Time zones · I4.04 Time display format
- Search terms:
store UTC·instant versus local·convert at display