How this site is tested
A tool site can tell you it is accurate, or it can show you the tests. This page sets out how the answers here are checked, with the numbers — including the times the checks found us wrong.
Every tool here runs in your browser, so there is no server to point at and no laboratory to invite you into. What we can show instead is the testing: what is checked, against how many cases, what it has caught, and what it still cannot see.
The suite, as at 10 August 2026
- 1,240 automated tests passing, plus 4 skipped, on the date at the top of this page. The standing claim is the one that does not go stale: more than a thousand.
- Three of those test files run six times over, once under each of six deliberately awkward host time zones — UTC, Los Angeles, Sydney, Kiritimati at UTC+14, Niue at UTC−11 and Kathmandu at UTC+05:45. A calculation that only works where the person who wrote it happens to live fails here rather than in your browser.
- Everything runs on three JavaScript engines carrying three different releases of the world’s time zone data.
The standing claim between reviews: this site carries more than a thousand automated tests. The exact figure belongs to the date beside it.
The times the tests found this site wrong
A testing page that lists only successes is marketing. These are defects our own checks caught.
A calendar function that had been wrong since it was written
The function measuring a calendar interval — the years, months and days between two dates, which every date tool here sits on — disagreed with the reference implementation on2,259 of 1,020,000 boundary-targeted date pairs, and had done from the day it was written. It is corrected, and a differential run against the reference now blocks every change.
Why it survived: a sample that could not reach the defect
This is the most useful thing on this page. The evidence recorded for that function was“40,000 random date pairs, zero mismatches”. The measurement was real, and incapable of finding the bug.
The two algorithms can only disagree when the starting day of the month exceeds the length of a later month — 31 January measured into February, and cases of that shape. Random pairs land there about 0.07% of the time, so a random sweep returns zero for a correct implementation and a broken one alike. Re-run with the known-broken code in place, it reported zero again.
A test that cannot reach the bug reports zero, and zero reads as proof. That sweep is now an enumeration of the month-end boundary, and the fixture keeps the known-wrong algorithm inline and asserts it still catches it. “Zero mismatches” can no longer mean “the test reached nothing”.
A colour nobody could see
Colour contrast here is a unit test that parses the real stylesheet and checks every foreground-and-background pair in both themes. It immediately caught an inherited control border at 1.44:1, and later a pair of already-approved colour tokens at 4.25:1, under the 4.5:1 floor for body text.
It exists because the automated accessibility audit renders one theme and checks text contrast but not non-text contrast: an unreadable dark palette, an invisible input border and an invisible focus ring all score a perfect 1.00. Its maths is verified against the canonical boundary greys — #767676 is 4.54:1 on white and #777777 is 4.48:1.
A page that looked like it was still loading
The type checker does not cover the interactive layer. A function returning an object was assigned to a variable typed as text inside an interactive component, and the type check reportedzero errors. In the browser that component failed as it started up, leaving its result box on its placeholder — a page that looks like it is still loading, forever. Nothing automated found it; opening the page did, which is why a real browser pass is a required step here rather than a courtesy.
And before any of it was built
The correctness research this site’s build specification was written from was reviewed adversarially before the first line of code, and 74 defects in it were confirmed, 5 of them critical — including a core algorithm that was wrong. The specification was then written from the corrected research rather than the original, which is why that number belongs to the research and not to the spec: getting the attribution right matters on a page whose central argument is that a true measurement of the wrong thing still reads like evidence.
Three engines, three sets of world data
Zone rules, zone names and month names are not written by us: they ship with the engine, and they change. So the suite runs on three, each carrying a different vintage:
- Node 22.13.1 — CLDR 46.0, time zone data 2024b
- Node 24.11.1 — CLDR 47.0, time zone data 2025b. The pinned, gating version
- Node 26.7.0 — CLDR 48.0, time zone data 2026c
The whole suite passes on all three, spanning three CLDR releases and three time zone data releases — so a result that depends on which data version a browser carries is caught here, not shipped.
What runs on every change
The built site is checked as an artefact, not as source. A script opens the files a visitor receives and asserts what is in them: that pages mounting no interactive component ship no JavaScript at all, that each tool page renders its content on the server rather than materialising it later, and that no advertising code is present while ads are switched off. Reading the source tells you what the author meant; the built files tell you what was shipped.
Interactive code is size-budgeted at 25 kB per tool, and that budget is measured against the tool’s own code with any generated data table counted separately against a budget of its own. The distinction is not bookkeeping. The time zone converter’s bundle is just under 30 kB, of which roughly 14 kB is the list of zones it has to offer you — so a single conflated number would have read as a breach, and the two obvious ways to make it go away were to raise the limit for every tool or to stop counting the table at all. Both hide something real, so the check was split rather than relaxed: a data table can no longer grow quietly inside a code budget. The exact figures are printed on every build; they are rounded here because a byte count in a sentence goes out of date on the next dependency bump, and a stale number is worse than an approximate one.
The same commit is built twice and the output compared. Any difference means something non-deterministic reached the page, most likely a build-time date — correct on the day it deployed, silently wrong for as long as the page stayed cached.
Server-rendered HTML and the page after it becomes interactive are compared element by element, and must be identical. Layout shift measures zero in a real browser on every tool page, including the case a lab test cannot produce: a lab profile starts with empty storage, so it never sees the shift a returning visitor gets when saved rows replace an empty state. That reload is checked by hand.
Rules enforced by a test, not by agreement
All the date logic lives in pure, tested functions, and the interactive components may not do date arithmetic at all. A lint names each banned construct outright and fires every pattern at a string it must match, so a rule quietly broken by an edit cannot report a clean codebase forever. A second test bans asserting on wording the browser’s international data owns — month and zone names — building its forbidden vocabulary from the engine at test time so it updates itself. A third requires every test to make at least one assertion, so a test that checks nothing cannot report green.
Why mechanise rules everyone agrees with? Because one of these rules was broken within the hour by the person who had just written it down. The rules that matter are the ones that go red.
Where the time zone rules come from
Your own device. Your browser ships a copy of the IANA Time Zone Database and this site reads offsets from it rather than bundling its own copy of the rules, so there is no table of transitions here to go stale — but your device’s copy can, and this site cannot detect it. What that means in practice is on time zone changes.
One dataset here is ours, and it belongs in this section rather than being quietly left out. The list of zone and place names is generated from pinned copies of IANA, GeoNames and CLDR data, because no browser interface exposes which country a zone belongs to. It is versioned at tzdata 2026c and CLDR 48.2.0, and it can go out of date: a zone added to the database after those versions will not appear in the picker until the table is regenerated. The offsets would still be right — they come from your browser — but the zone might not be offered.
Everything you enter — timers, saved cities, countdowns — is computed in your browser and stored only on your device. This site is supported by ads: when advertising is enabled, Google may set cookies and collect data such as your IP address, subject to your consent choices.
Details that only show up when you measure
- Offsets are carried in seconds, not minutes. Africa/Monrovia ran 44 minutes and 30 seconds behind UTC until 7 January 1972 — after the 1970 floor these tools work from, so a minute-typed offset would make a real historical value unrepresentable.
- A daylight-saving shift is not always an hour. Lord Howe Island shifts by 30 minutes and
Antarctica/Trollby two, so any code adding or subtracting 3,600 seconds is a bug waiting for the right date. - The legal span of offsets is +14:00 to −12:00 — twenty-six hours — so one conversion can land two calendar days from where you started, which thetime zone converter shows rather than capping at one day.
- Leap seconds are ignored by the clock in your browser: every day in JavaScript is exactly 86,400,000 milliseconds. The last leap second was inserted on 31 December 2016, and the 27th General Conference on Weights and Measures resolved in 2022 that the maximum value of UT1 minus UTC will be increased in, or before, 2035.
What we have not checked
- Two daylight-saving values were derived by hand. Cairo in 2028 and Lord Howe Island in April 2026 were read off rule files rather than measured. Treat them as unverified.
- Time zone abbreviations differ between data sources, so the tests assert offsets only, and results are labelled with an explicit offset rather than three letters.
- The 875,520-sample verification has not been repeated. The wall-clock resolver — the function turning “9am in Bangkok” into an actual instant — was checked over 875,520 generated samples with zero errors, against the obvious alternative implementation’s 276 wrong instants and 1,330 wrong ambiguity flags across 3,104 cases. That run used a deliberately out-of-date copy of the time zone data and has not been repeated. The algorithm does not depend on the data version, so it should hold — but “should hold” is not “was measured”.
- Desktop notifications were checked against documentation, not on a device.They are unavailable in nearly every mobile browser, which is why nothing here is positioned as a reliable alarm.
- This is not a certified timing device. Nothing here should be relied on where the answer matters legally, financially or medically. Check an official source.
Corrections
If something here is wrong, we would rather know. A specific report — the tool, the inputs, the answer you got and the answer you expected — is worth more than any amount of praise, and a correction that lands gets recorded rather than quietly patched. Write viacontact. The primary references are onsources, including theIANA Time Zone Databaseand WCAG 2.2; every change is on thechangelog. This site is built and maintained by an individual developer based in Singapore — more on the about page.