Ground truth · the record that keeps revising
The Past Has a Version Number
Ask any computer what the local time was in Cancún on a July afternoon in 1990 and it will answer without hesitating. The answer is not a fact. It is a version. It said six in the morning, then said seven for twenty-three years, and in September 2024 it went back to six. This page compiles every archived release of the IANA time zone database that one fixed compiler can read, 249 of them across thirty years, and diffs what each one says about moments that had already happened when it shipped.
Start with one afternoon
Pick an instant: noon UTC on 1 July 1990. Pick a place: Cancún. Every computer in the world consults the same database to turn the first into the second, and here is every answer that database has given, read live from the compiled releases themselves.
loading the compiled releases…
Three answers, and the third is the first one again. Between 2001 and 2024, a machine asked about that afternoon said seven in the morning. Before 2001 and after September 2024 it says six. Nothing happened in Cancún in 2024. What happened is release 2024b, whose changelog says: “Historical transitions for Mexico have been updated based on official Mexican decrees. The affected timestamps occur during the years 1921-1927, 1931, 1945, 1949-1970, and 1981-1997.” Somebody had gone back to the decrees.
It is not a quirk of one Mexican resort. Here is Tijuana, on a summer afternoon two decades earlier, and the same shape: an answer, a different answer that stood for twenty-six years, and then a return, this time nine months ago.
loading…
People were alive on that afternoon. They caught buses, clocked in, missed appointments. Whether the clock on the wall in front of them said four or five is, as far as every computer is concerned, a question that was reopened in December 2025 and answered differently. Release 2025c, in full, on this point: “Baja California agreed with California’s DST rules in 1953 and in 1961 through 1975, instead of observing standard time all year. (Thanks to Alois Treindl.)”
What the database says about itself
The IANA time zone database, tzdb, is the thing underneath almost every clock you will use today: it ships in Linux, macOS, Windows, Android, iOS, Java, Python, and every browser. When your phone shows a timestamp on a photograph from 2003, this database decided what it says.
It would be easy, and wrong, to call that the canonical record of what time it was. The database itself refuses the title, in writing, in the file it ships explaining its own theory:
The tz database is not authoritative, and it surely has errors.
tzdb, theory.html, under “Accuracy of the tz database”
In short, many, perhaps most, of the tz database’s pre-1970 and future timestamps are either wrong or misleading. Any attempt to pass the tz database off as the definition of time should be unacceptable to anybody who cares about the facts. In particular, the tz database’s LMT offsets should not be considered meaningful…
tzdb, theory.html
So the interesting question is not whether an authority changes its mind. It is the gap between what this thing says of itself and the job the world has quietly given it. Nothing in your phone's photo viewer carries that disclaimer. The measurement below is of the record people actually consult, on its own terms: not how often it is wrong, which nobody can know, but how often it has changed its answer about a moment that had already happened.
What was already known, before this page
A good deal, and it is worth being exact about it, because three of the four things this page set out to do turned out to exist already. The scouting pass that found them reshaped the piece, which is the best thing that could have happened to it.
- The past-versus-future census exists and is peer reviewed. Mani, Barford, Durairajan and Sommers, What time is it? Managing Time in the Internet (ACM ANRW ’19), built a Python parser over the source rule files and reports, verbatim: “Using the parser, we identify 2,283 updates to the zone and DST rules across all of 240 TZDB releases over the past 26 years.” It classifies updates as past-facing or future-facing by exactly the method used here, comparing each update's time range against the release timestamp, and finds “that a majority of the release updates affect timestamps in the past”. IANA's own tz-link.html links it: “What time is it: managing time in the internet analyzes the database longitudinally.”
- The compiled per-version transition tables are already published for the recent era. A0 TimeZone Migration, also linked from tz-link.html, serves one JSON file per zone containing every transition under every version. We downloaded Africa/Cairo.json and confirmed it first-hand: 75 versions, 2013c through 2025c, each with its release date and its full transition list. It also ships a browser tool that diffs any two versions of a zone.
- The maintainers ship their own normalised transition dump. Since 2016g the combined tzdb-*.tar.lz release carries to2050.tzs, generated by zdump -i -c 2050. We extracted tzdb-2026a.tar.lz and found it, 593,841 bytes of it. 49 releases carry one.
- The changelog itself says so. From release 2016b the NEWS file uses structured section headings. We parsed all 311 release blocks in the cumulative NEWS: 53 releases carry such headings and 38 of them name a change to the past in as many words.
So the headline is not new, and this page does not pretend otherwise. What appears to be unpublished, and is what the rest of this page is, is the part everyone counts events instead of measuring: by how much the answer moved and for how long the wrong one stood, which places have been revised most, how long a statement about local time survives before something changes it, and the compiled-table record reaching back to 1996 rather than 2013. Plus two things a paper cannot do: an instrument that sweeps every version at once instead of comparing two, and a page that asks your own browser which side of each disagreement its built-in copy is on.
How this was measured
Every archived tzdata release was downloaded from IANA's release archive: 272 of them, from 1993 to 2026. Each was compiled to the binary TZif files that operating systems actually read, and every transition in every zone was extracted and compared, release against release.
One compiler, held fixed
The single decision that makes the measurement mean anything: every release was compiled by the same compiler, the reference zic from tzcode 2026c. Compiling each release with its own contemporary zic would mix two effects that could never be separated afterwards, because zic's own output format changed repeatedly (it switched its default from -b fat to -b slim in 2020b, which alone would make every zone on earth appear to change on that one day). Holding the compiler fixed makes every difference a data difference by construction. The cost is stated plainly: a modern compiler reads 1996 data the way 2026 reads it, not the way 1996 did.
A 54-line patch, and the proof that it is inert
Modern zic cannot read old tzdata at all. Two lines of the australasia file, describing Australian daylight saving from 1990 onward, use a feature called a year type, which upstream removed in 2015:
Rule AS 1990 max even Mar Sun>=22 3:00 0 -
Rule AS 1990 max odd Mar Sun>=1 3:00 0 -
The old compiler resolved even and odd by shelling out to a script, yearistype.sh, shipped alongside the data, whose entire content on this point is that a year is even if its last digit is one of 24680 and odd if it is one of 13579. Those exact semantics were put back into the modern compiler in a 54-line patch, committed with the rest of this work. It is required to hold to one rule: it must change nothing else. The verifier compiles seven releases twice, with the stock compiler and the patched one, and requires the output to be byte-for-byte identical.
With the patch, 249 consecutive releases compile cleanly, from 96h dated 1996-05-09 to 2026c dated 2026-07-08. The 23 that do not are the 23 oldest, 1993-11-22 through 1996-03-19, and they fail for a different and honest reason: they contain rules that fire twice at the same instant, which later zic rejects as an error rather than resolving silently. They are excluded and listed, not patched around. A finding falls out of that on its own: the reference implementation can no longer read its own database's first three years.
The cutoff, which is the whole argument
Between release R dated D and its successor R′, a difference at instant t is a rewrite only if t < D. If t had not yet happened when R shipped, R was predicting, and a prediction that turns out wrong is not the record changing its mind about history. Using the earlier release's date, rather than the later one's, gives every second in the window between two releases to prediction and never to rewriting. It is the conservative side of the line, and it is why a genuine case falls outside: 2023c reverted Lebanon's data to model that country's daylight-saving chaos, and every instant it touched was still in the future when its predecessor shipped.
Three separations, because they are three different claims
- Offset, not abbreviation, not the DST flag. tzdb ships releases whose NEWS says, in as many words, “Changes to past time zone abbreviations” and “Changes to past tm_isdst flags”. Those do not change what the clock read. They are counted separately throughout.
- Dated instants, not pre-history. Every zone has a first transition, and before it sits a local mean time value derived from an assumed longitude. theory.html says those “should not be considered meaningful”. Changes to them are counted separately and never appear in the headline figures.
- Three windows. All of recorded time; the post-1970 era tzdb vouches for; and the window from 1996-05-09, the first release in this series, which is the only window in which every revision that ever happened is visible to us. Outside it, every count here is a lower bound.
The census
Of 248 consecutive release pairs, 145 changed the recorded UTC offset at some instant that had already happened, and 118 changed one after 1970. That is 47.6 per cent of releases quietly editing a settled, post-1970 clock reading somewhere on earth. Across 604 zone names, 479 have had their settled past changed at least once and 234 have had their post-1970 past changed.
Asia/Gaza leads the count for a reason its own NEWS entries make plain: its daylight saving start and end are frequently announced late or changed mid-season, so the database records them after the fact. That is a different phenomenon from Antarctica/Vostok, which leads the duration table below because one release moved a single unbroken stretch of twenty-eight years.
Five specimens
The aggregate is the finding; the individual cases are why it is worth having. Each of these was located by the measurement and then run down in the database's own changelog, data-file comments and mailing list, which is the order that matters: found in the artifact first, explained from primary sources second.
Sitka, and the largest correction in the whole series
The biggest single change to a settled instant anywhere in 249 releases is 29 hours, 57 minutes and 34 seconds, and it is a minus sign. America/Sitka entered the database in release 2011c with a pre-1867 local mean time of -14:58:47. The correct value is +14:58:47: before the United States bought Alaska, Sitka kept Russian days and was on the far side of the date line. The wrong sign put the town roughly ninety degrees of longitude into the Pacific.
It stood through 9 releases and 217 days, and was caught by a reader:
For local mean time to jump by 5.6 hours, implying that the city jumped 89 degrees to the east, would be a neat trick. Obviously the first offset is meant to be +14:58:47, and the city jumped by 24 hours or 360 degrees, crossing the IDL.
Zefram, tz mailing list, 2011. The fix shipped in 2011l; the release notes do not mention it.
Vostok Station, where the record answered with somebody else's clock
Ask the database what time it was at Vostok, in the middle of the Antarctic ice sheet, on a July day in 2010. It has given five answers. Moscow summer time in 2001a. Then +06 for twenty-two years. Then, in December 2023, +07. That last change moved a single unbroken stretch of twenty-eight years, which is why Vostok tops the duration table above with 94.2 per cent of its post-1970 recorded life revised.
The change came from the station chief writing to the mailing list to announce a decision, and answering a follow-up question almost in passing:
(In response to the question “Has local time at Vostok been UTC+6 ever since 1957, or has it changed before?”): No. At least since my antarctic career start, 10 years ago, Vostok base has UTC+7.
Zakhary V. Akulov, chief of Vostok station, quoted in tzdb's antarctica file
The maintainer's reply on the list was: “Ouch. TZDB has been wrong for Vostok for at least 10 years. I will try to correct this.” And for part of that time the record had not merely been wrong, it had been somebody else's: from release 2022b, Antarctica/Vostok was a link to Asia/Urumqi, so a computer asked about the ice sheet answered with Xinjiang's data.
Jan Mayen, where a typo lasted six days
Release 2021b pointed Atlantic/Jan_Mayen at Europe/Berlin. That was a mistake, and Norway is not Germany: German wartime and post-war daylight saving that Norway never observed, and ten and a half minutes of local mean time, changed the answer for a great deal of pre-1970 Jan Mayen. It was reported the next day and fixed in 2021c. The wrong answer was the official one for 6 days and 22 hours, one release long, which is a useful reminder of what an aggregate over shipped releases cannot see: how many machines ever installed that one.
Fix typo that linked Atlantic/Jan_Mayen to the wrong location (problem reported by Chris Walton).
tzdb NEWS, release 2021c, filed under “Changes to Link directives”. This is the one release in the whole graded era where our measurement finds a past offset change and the changelog does not say so.
Tokelau, settled by telephone
Tokelau crossed the date line at the end of 2011, which is famous. What is not is that the correction rippled backwards to 1901. Release 2012e moved the pre-2011 offset from -10 to -11, changing the answer for every instant in more than a century of Pacific/Fakaofo's recorded life. The evidence was a complaint and some phone calls:
we got a complaint a few weeks ago, from a user in Tokelau that our Tokelau time on timeanddate.com was one hour ahead of the actual time there… we double checked by calling hotels and offices based in Tokelau asking about the time there, and they all told a time that agrees with UTC+13.
Steffen Thorsen, tz mailing list, 2012-07-25
The database's own comment on the older figure now reads: “Go with Thorsen and assume Shanks & Pottenger are off by an hour starting in 1901.”
Gaza, which is revised because the announcements come late
Asia/Gaza tops the count with 13 separate releases changing its settled past, every one of them touching a post-1970 instant. The reason is not carelessness anywhere, and the NEWS entries make it plain. Release 2013c corrected six already-past transitions in one go, four of them daylight-saving changes in 2008 through 2011 whose dates and hours the database had recorded wrongly. Release 2020d corrected 2015, 2019 and 2020 in a single release. When a government announces a clock change days before it happens, or changes it after, a database that has to guess in advance will spend the following years correcting itself.
How long a statement about local time lasts
Counting events flatters the database, because most events are small. The better question is the one a person would ask: if I pick a moment in the past and a place at random, what is the chance the record has since changed its mind about what the clock read? Because the compiled data is piecewise constant, that can be computed exactly rather than sampled.
0.983 per cent, for an instant drawn uniformly from the window this study fully observes, 1996-05-09 to 2026-07-08, and a zone drawn uniformly from the 604.
2.100 per cent, for an instant drawn from the whole post-1970 era. That figure is a lower bound: revisions made before 1996 leave no trace in this series.
About one moment in a hundred, in the last thirty years. It is small enough that the database is clearly doing its job and large enough that “what time was it” is, for 134 of the 604 zones, a question with a version history.
The delay
When the record does change its mind, it is almost never prompt. Mean time from the instant to the release that first changed it, inside the fully observed window: 2712 days, about seven and a half years.
Share of revised instant-mass by how long the first revision took to arrive. Only 0.68 per cent arrived within a month.
The size of the correction
This is the sharpest thing in the study, and it was not what we expected to find. When the record changes its mind about a post-1996 instant, the answer moves by a whole number of hours almost every time.
Which says what these revisions actually are. They are not refinements of a longitude or a minute of local mean time. They are the discovery, years later, that a country was or was not on daylight saving that summer, or had or had not moved a zone boundary. Somebody's summer went missing from the record and was put back.
The tail is where it gets strange. The largest post-1970 corrections in the series are around twenty-five hours, and they are date-line moves: Pacific/Fakaofo, when Tokelau crossed the line at the end of 2011, and its earlier history was reconsidered with it.
Grading the changelog against the artifact
From 2016b the database's NEWS carries structured headings, and some say plainly that a release changed the past. That makes a rare thing possible: an independent, human-written statement of what each release did, to check a measurement of what each release actually did. 54 releases can be graded this way.
Agreement is 92.59 per cent, and the four disagreements are the interesting part. Every one of them was run down. None was a fault in the measurement, and one was a fault in the checker.
- 2016e. NEWS declares “Changes affecting past timestamps”; we measure no offset change at all. Reading the entry settles it: the two items are that uninhabited places now use the abbreviation -00 instead of zzz, and that Asia/Baku's 1992 transition “from +04 (DST) to +04 (non-DST)” moved. The first is an abbreviation, the second is a DST flag at an unchanged offset. Our measurement records exactly that: 19 zones with a changed past abbreviation and 1 with a changed DST flag. The changelog filed under “past timestamps” a release that did not alter a single clock reading.
- 2016j. Its past-timestamps item is a new zone, Asia/Atyrau, split off with a different history from the zone it came from. No existing name changed, so no diff exists to find. Its separate abbreviation item says “Asia/Gaza and Asia/Hebron now use ‘EEST’, not ‘EET’”, and we measure a past abbreviation change in exactly 2 zones.
- 2023c. The Lebanon revert, described above: real, and on the prediction side of the cutoff by design.
- 2021c. The only case in the other direction. We measure a past offset change in one zone and NEWS files it under “Changes to Link directives”: “Fix typo that linked Atlantic/Jan_Mayen to the wrong location”. The answers a computer gives for Jan Mayen changed; the changelog's category does not say so.
The checker's own bug is worth naming, because it is the failure mode this whole apparatus exists to catch. It first matched only headings beginning “Changes to”, and the 2016 releases write “Changes affecting past timestamps”. That scored three releases as changelogs hiding a past change, when the changelog had said so plainly in the other wording. Agreement was 88.89 per cent until the regular expression was fixed, and the three vanished. A cross-check that grades somebody else's work is exactly where an error becomes an accusation.
The control: what the historian's build says
In 2021b tzdb began merging zones whose clocks had agreed since 1970, which replaces the pre-1970 history of the merged name wholesale. NEWS 2021b is explicit that this is a packaging decision, not a correction:
This does not affect post-1970 timestamps, and timezone historians who build with ‘make PACKRATDATA=backzone’ should see no changes to pre-1970 timestamps.
tzdb NEWS, release 2021b
If that is true, a default build will show a burst of apparent rewriting at 2021b that a historian's build does not. So both were built, using upstream's own ziguard.awk mechanism rather than an improvised one, over the 25 releases where that mechanism runs unchanged.
The claim holds, and the size of it is worth seeing: at 2021b, 38 zones' settled past changes in a default build and 13 in the historian's, so two thirds of that release's apparent rewriting is the merge policy. At 2022b it is 31 against 5. Across the compared releases the totals are 276 and 191. Post-1970 the two columns barely move, which is the part NEWS promised.
The control also cuts the other way in places, and that is left in rather than tidied: at 2022f the historian's build shows more changed zones than the default, because backzone carries its own history and that history gets corrected too.
The instrument
Every published tool for this compares two versions. This one sweeps all 249 at once. Give it a place and a moment and it will show you every answer the database has ever given, collapsed into runs, with the release that changed each one.
Your browser is the 250th witness
Every browser ships its own copy of this database, and it is not necessarily the newest one, or even any single one: vendors patch, and the copy in Chrome comes through ICU while Firefox overrides some of ICU's behaviour with tzdb's own files. There is no JavaScript API that reports the version. But there does not need to be one, because this study knows hundreds of instants at which two releases disagree, and each of those is a question only a particular vintage of the database can answer a particular way.
So the page asks yours. Below, your browser is put through 400 such questions, drawn from the measured disagreements, all of them post-1970 and all of them whole numbers of minutes apart.
This is where the page's own subject bit the page. The first version of the fingerprint admitted any instant where two consecutive releases disagreed, which is wrong for exactly the reason Cancún is interesting: if a later release changed the same instant again, a browser giving the older answer may be newer than the release in question rather than older, because it has taken a reversal. On this machine the unsound version reported the browser's copy as internally contradictory. A probe is now admitted only if the changed value survives to the newest release, which makes the inference sound in both directions. 228 candidate probes were rejected on that ground.
interrogating your browser…
One honest complication, and the page would be lying by omission without it. Engines do not all report a time zone offset to the same precision, and JavaScript's oldest way of asking, getTimezoneOffset, is specified to return whole minutes. So for instants in the local-mean-time era, before standard time arrived, an offset that is not a whole number of minutes can come back rounded, and your browser can disagree with the compiled data for a reason that has nothing to do with which version it ships. That is why every probe above is post-1970 and a whole number of minutes apart. Rather than repeat what a bug tracker says, the panel below asks your engine two different ways and prints what it actually does.
measuring…
What this does not claim
- Not that the database is unreliable. The opposite, if anything. About one moment in a hundred over thirty years, mostly in places whose governments announce late, is the signature of something being maintained carefully against genuinely hard evidence. The claim is only that the answer has a version, and almost nothing that consumes the answer says so.
- Not that these are errors. A change is a change. Whether the old answer or the new one is right about the world is a question about archives in Baja California and Xinjiang and Ulaanbaatar, not about this data, and this page does not adjudicate it.
- Not a complete count. For instants before 1996-05-09, every figure here is a lower bound, because a revision made before the first release in the series left no trace we can see. The 23 refused releases are 1993 to early 1996.
- Not what a 1996 computer would have said. One modern compiler reads all 249 releases, which is what makes the diffs mean something, and also means old data is read the modern way.
- Nothing about pre-history. Local mean time changes are counted and reported separately and never enter a headline, on the database's own advice.
- Not a claim about backzone in the default figures. The default build excludes it, as upstream's default does. The historian's build is run as a control over the releases where upstream's own mechanism runs, and both columns are shown.
Check it yourself
Everything above is derived from files this page also serves. The lab notebook is research/tzdb-rewrites/: build.mjs downloads nothing and compiles everything, analyze.mjs does the diffing, survival.mjs does the interval arithmetic, newscheck.mjs grades the changelog, export.mjs writes what this page loads, and ask.mjs is the command-line twin of the instrument above, reading the same files and doing the same lookup, so that a disagreement between them would be visible.
The verifier is verify.mjs. It checks the parser used here against two entirely independent readers of the same bytes, Python's zoneinfo module and the reference zdump that tzdb ships; it requires the compiler patch to be byte-identical to stock zic wherever stock zic can run; it recomputes every figure printed above from the artifacts; and it carries deliberate corruptions that must turn it red, because a check that cannot fail is not a check. No count of checks is quoted here, on purpose: a number describing the verifier is the one number the verifier cannot keep honest.
This page also checks itself. Every bolded figure above is compared against the loaded data when the page opens, and a red banner appears at the top if any of them has drifted from the artifact it came from.