Day 17 — Time Zones Are a Nightmare

Yesterday I wrote about how 2026-05-24T14:30:00Z won the format wars. That Z at the end, it turns out, is quite important. It says Zulu, it says UTC, it says: I am refusing to participate in the nightmare that is Timezones.

However, today we participate.


The lie you were told in school

There are 24 time zones, one for every hour, neat 15° slices of the globe.

There are not. There are at least 38 named offsets in active use right now, and the list changes a few times a year.

Some of them are not on the hour:

  • India is at UTC+5:30. The whole country, one zone, half-hour offset.
  • Nepal is at UTC+5:45. Forty-five minutes. Because Nepal decided in 1986 that it wanted its civil time anchored to the meridian passing through Gauri Shankar, not Delhi.
  • Newfoundland is at UTC−3:30.
  • The Chatham Islands are at UTC+12:45.

The range isn’t 24 hours either. It runs from UTC−12 to UTC+14, a 26-hour spread, because Kiribati got tired of being split by the international date line in 1995 and just moved the line. One day the Line Islands woke up and it was tomorrow.

Then there’s China, which geographically spans five time zones and politically uses one (UTC+8), so in the far west of Xinjiang the sun rises at what the clock insists is 10 AM. North Korea changed its offset twice in the 2010s, from UTC+9 to UTC+8:30 in 2015 to mark liberation from Japan, then back to UTC+9 in 2018 to align with Seoul during a diplomatic thaw.

Time zones are not geography. Time zones are politics with a clock face glued to the front.


How we got here

Before about 1850, every town in the world ran on its own clock. Noon was when the sun was overhead here, which meant noon in Boston was several minutes off from noon in New York, which was off from Philadelphia, which was off from everywhere.

Nobody cared, because nobody was traveling fast enough for it to matter.

Then the railroads showed up.

When your train leaves at “noon” and arrives at “3 PM” and every station defines noon differently, you can’t print a schedule. Britain rolled out Railway Time (GMT everywhere) in the 1840s. The American railroads, bless them, didn’t wait for permission. On November 18, 1883, they unilaterally divided the United States into four zones. Newspapers called it “the day of two noons” because clocks across the country jumped, sometimes forward, sometimes back, to land on the new shared time.

The following year, in October 1884, twenty-five countries met in Washington for the International Meridian Conference and made it official. Greenwich is 0°, the universal day starts at midnight in Greenwich, every other place is some offset from that.

France abstained. France wanted Paris. France held out until 1911.


The “database” holding the world together

When your phone shows you the right time after you land in Tokyo, when your calendar correctly reschedules a meeting because Mexico canceled DST a few years ago, when your server logs all line up across a deploy in three continents, that all happens because of a single, voluntarily maintained text file.

It’s called the IANA Time Zone Database, also known as the Olson Database, after Arthur David Olson, an NIH employee who started maintaining it in 1986 as a side project. Today it lives under IANA stewardship and is primarily maintained by Paul Eggert, a UCLA computer scientist who has been doing this, mostly alone, for decades.

Every Unix system, every Linux distro, every Mac, every iPhone, every Android phone, Java, Python, Go, Rust, Postgres, browsers, every piece of software that knows what time it is, gets its time zone rules from this database. The release cadence is multiple updates per year, almost always triggered by some country’s parliament deciding to change DST rules with three months' notice.

The format is something like America/New_York, Europe/Berlin, Asia/Kolkata, Pacific/Kiritimati. Area, slash, location. Not EST, not GMT+5, because those are offsets and offsets aren’t enough. The rules are what you need, because the rules change with politics.

The whole arrangement is held together by a small group of volunteers, a mailing list, and Paul Eggert’s continued willingness to keep doing this. If he ever stops, somebody else will have to start.


Why this is one of the hardest problems in working programmer software

A few categories of pain, none of them solvable, all of them shipped to production daily:

1. Ambiguous local times. When the clocks fall back in November, the hour from 1:00 to 2:00 AM happens twice. If a user schedules a meeting at “01:30 local time” on the wrong day, which 01:30 do they mean? There is no correct answer. Your software picks one and someone shows up an hour off.

2. Nonexistent local times. When the clocks spring forward in March, 2:30 AM doesn’t exist. If somebody’s medication-reminder app is set for 02:30, what does it do that morning? Skip? Run at 03:30? Run at 01:30 the previous hour? There is no correct answer.

3. Future timestamps are mutable. If you store a meeting as “October 15, 2027 at 3 PM in Mexico City,” and Mexico cancels DST between now and then, which it did, in 2022, the meeting moves. The number of hours from now until that meeting changes after you saved it. The cardinal rule, the only thing that saves you, is this: store UTC and the IANA zone name separately, never store a local timestamp alone, and recompute on display.

4. JavaScript’s Date object. It’s not great but I worte more about it here, There is a fix called the JavaScript Temporal API. It’s technically here now, though browser support is still rolling out, and we will all be happier when it’s fully supported everywhere.


The list of lies (about time)

There’s a famous post called Falsehoods Programmers Believe About Time, and a partial sample from the time-zone section gives you the texture:

  • “There are 24 time zones.” (38+, give or take, depending on the week.)
  • “A day is 24 hours.” (DST transitions make some days 23 or 25.)
  • “Time zones don’t change.” (They change several times a year.)
  • “If I store the UTC offset I don’t need the zone ID.” (You do, for any future date.)
  • “UTC is a time zone.” (UTC is a time scale. Zones are offsets from it. This distinction is going to matter more than it sounds like it should.)

All are gotchas that programmers encounter when working with time zones.


The ultimate example of technical debt

The time zone system isn’t broken, per say… it’s working exactly as designed.

It was designed by railroad executives in 1883, ratified by diplomats in 1884, and then handed off to every country on Earth to amend at will. Every president who has ever moved a DST date for political reasons, every dictator who has ever changed the national offset to flatter a neighbor, every parliament that has voted to abolish daylight saving without specifying when, has added their fingerprint to the IANA database.

It is a working international system. It is also a Rube Goldberg machine running on a tar pit, held aloft by Paul Eggert and a mailing list.

If you ever thought Timezones were bad, tomorrow it gets worse. We’re going to talk about Daylight Saving Time, and the specific, named software disasters it has caused.


Sources

  • Nepal Standard Time — Wikipedia. Details Nepal’s 1986 decision to anchor civil time to the Gauri Shankar meridian (UTC+5:45).
  • Time in Kiribati — Wikipedia. Covers the 1995 shift of the International Date Line, creating the 26-hour global spread.
  • Time in North Korea — Wikipedia. Documents the geopolitical shifts between UTC+8:30 and UTC+9.
  • Day of Two Noons — Wikipedia. History of American railroads unilaterally standardizing time on November 18, 1883.
  • International Meridian Conference — Wikipedia. The 1884 agreement that established Greenwich as 0° (and France’s holdout until 1911).
  • IANA Time Zone Database — Wikipedia. History of the Olson database, its maintenance by Arthur David Olson and Paul Eggert, and its fundamental role in modern computing.
  • Daylight saving time in Mexico — Wikipedia. Details the national abolishment of DST in October 2022.
  • JavaScript Temporal API — TC39 Documentation. The modern fix for JavaScript’s notoriously broken Date object (currently rolling out to browsers).
  • Falsehoods Programmers Believe About Time — Noah Sussman’s canonical post detailing the myriad ways developers misunderstand time.

I’d appreciate a follow. You can subscribe with your email below. The emails go out once a week, or you can find me on Mastodon at @[email protected].

/ Programming / History / Time / 30daysoftime / Software