We're used to a day being 24 hours. But twice a year that isn't true: when the clocks go forward and back, one day lasts 23 hours and another lasts 25. One hour is either repeated twice or vanishes entirely. A small thing, yet it breaks a surprising amount.
What this throws off
- The logic "exactly 24 hours have passed" is off by an hour on such a day.
- A scheduled task set for a time inside the missing hour never runs at all; one set for the repeated hour runs twice.
- Calculations of "hours worked in a day", "end of day", "how much to shift by" - all quietly drift.
This isn't theory. On one live project we ran straight into that shift - right on the difference between "24 hours" and "one calendar day". Ever since, we treat time with respect.
Why UTC saves the day
UTC is a single world clock with no daylight saving switch. In UTC a day is always exactly 24 hours, and an hour never repeats or goes missing. So all the time inside the system - in the database, in calculations, in comparisons - we store and compute in UTC. There the arithmetic of time is honest and predictable.
There's a second reason too. Local time is a political thing: countries change the rules for switching the clocks, shift their zones, introduce and abolish daylight saving. If you store "10:00 local", a year later you can no longer say exactly which world moment that corresponded to. UTC never changes - it's a reliable point of reference you can always anchor to.
Time zone - only on the screen
The user, of course, needs to see their own local time, not UTC. So we convert to the time zone at the very last moment - when it goes to the screen. Inside, everything lives in UTC, and "10:00 Kyiv time" appears only where a person is actually looking at the time.
Store and compute a moment in time in UTC, and convert to a time zone only on output. Then the oddity of the 23- and 25-hour days stays at the very edge of the system, where it belongs.
A small thing that spares you a whole class of drifting bugs - "off by an hour, or on the wrong day".

