Time zones are a famous source of software bugs, and for good reason: they mix politics, astronomy and history into something that refuses to behave. Yet most time-zone disasters come from a few avoidable mistakes. This guide gives you the rules that keep time handling sane.
Why time zones are hard
Time zones are not fixed offsets — they change with daylight saving time, and the rules themselves change by government decision. Offsets range across the globe and even include half-hour and quarter-hour increments. A time without a zone is ambiguous, and arithmetic on local times can land on a moment that never existed or happened twice.
The one rule that fixes most of it
Store and compute in UTC; convert to local time only when displaying to a user. UTC has no daylight saving and never shifts, so timestamps are unambiguous and comparable. If every timestamp in your database and logs is UTC, an entire category of bugs simply cannot occur. The conversion to a friendly local time is a presentation step at the very edge of your system.
The daylight saving traps
- Adding 24 hours is not always "the same time tomorrow" — a DST change can shift it by an hour.
- Some local times do not exist (the spring-forward gap) or occur twice (the autumn fall-back).
- Time-zone rules change; relying on a hard-coded offset will eventually be wrong.
Displaying local time
To show a user their local time, convert the UTC instant using their time-zone identifier — like Europe/Riga — not a fixed offset, so daylight saving is handled correctly. Store the zone identifier if you need to render in the user’s zone later. Let a well-maintained date library do the conversion; never attempt the offset math by hand.
The takeaway
Store UTC, display local, use proper zone identifiers, and lean on a trusted library. Follow those rules and time zones go from a recurring nightmare to a non-issue.