Sun, Apr 19, 2026 08:14:00 UTC
Back to Blog

A Developer's Guide to Timezone Hell (And How to Escape It)

10 min read
timezonesdstutcbest-practicesexplainer
World map showing overlapping timezone boundaries and DST transitions

Timezones are the single most underestimated source of bugs in software. They look simple on the surface — just an offset from UTC, right? — but the deeper you go, the more edge cases you find. DST transitions create hours that happen twice and hours that don't exist. Countries change their timezone rules without warning. Some timezones are offset by 30 or even 45 minutes. And the worst part: timezone bugs are silent. They don't crash your app. They just produce subtly wrong results that nobody notices until the data is already corrupted.

The Golden Rules

After years of timezone-related bugs across thousands of codebases, the developer community has converged on a set of rules that prevent the vast majority of issues:

  • Store everything in UTC. Always. No exceptions. Convert to local time only at the display layer.
  • Use IANA timezone identifiers (America/New_York), never fixed UTC offsets (UTC-5). Offsets change with DST; IANA IDs handle this automatically.
  • Never do timezone math yourself. Use a library (Luxon, date-fns-tz, Joda-Time, NodaTime). The rules are too complex and they change too often.
  • Store the user's IANA timezone separately from timestamps. A timestamp is a moment in time; a timezone is a user preference.
  • Be aware of DST transitions. Scheduling "2:30 AM" on the night clocks spring forward will fail — that time doesn't exist.
  • Test with edge-case timezones: Asia/Kathmandu (+5:45), Australia/Lord_Howe (+10:30/+11:00 DST with 30-min shift), Pacific/Chatham (+12:45).
Compare any timestamp across multiple timezones

DST: The Hour That Doesn't Exist

When clocks spring forward, one hour vanishes. In the US Eastern timezone on the second Sunday of March, 2:00 AM jumps directly to 3:00 AM. Any timestamp between 2:00:00 and 2:59:59 is invalid on that date — it literally never happens. If your system schedules an event at 2:30 AM on that day, it will either fail, get silently skipped, or get shifted to 3:30 AM depending on how your datetime library handles it.

The reverse is equally treacherous: when clocks fall back, one hour happens twice. 1:30 AM occurs once in EDT, then the clock falls back and 1:30 AM occurs again in EST. A log entry timestamped "1:30 AM" on that night is ambiguous — you don't know which 1:30 AM it refers to without the UTC offset.

Countries That Changed Their Timezone Rules Recently

Timezone rules are political decisions, and governments change them with surprisingly little notice. Morocco switches to permanent DST then reverses the decision during Ramadan. Samoa skipped an entire day in 2011 when it jumped across the International Date Line. Russia has changed its timezone policy multiple times since 2010. Turkey abandoned DST permanently in 2016. This is why you use IANA timezone databases (updated multiple times per year) instead of hardcoded offsets.

The Weirdest Timezones

TimezoneOffsetWhat Makes It Weird
Asia/Kathmandu+05:4545-minute offset from UTC — not a whole or half hour
Australia/Lord_Howe+10:30 / +11:00DST shift is only 30 minutes instead of the usual 60
Pacific/Chatham+12:45 / +13:4545-minute offset AND 13+ hours ahead of UTC
Asia/Kolkata+05:30All of India uses a single timezone despite spanning 2,000 miles
Pacific/Kiribati+14:00The first place to see each new day — 14 hours ahead of UTC

If your date-handling code assumes timezone offsets are always whole hours, these zones will break it. If your code assumes DST always shifts by exactly 1 hour, Lord Howe Island will break it. If your code assumes UTC offsets max out at +12, Kiribati and Chatham will break it.

Practical Testing Checklist

  • Test scheduling across DST spring-forward (non-existent hour) and fall-back (ambiguous hour)
  • Test with Asia/Kathmandu to catch assumptions about whole-hour offsets
  • Test with Pacific/Auckland to catch assumptions about UTC offset range
  • Test date calculations that cross midnight in one timezone but not another
  • Test the display of dates for users in UTC-12 through UTC+14 (the full range)
  • Test sorting dates that were input in mixed timezones
Visualize timestamps across multiple timezones simultaneously