Intl timezone resolves
Check id timezone-present
What an ordinary browser yields
A named IANA zone such as 'Europe/Amsterdam' or 'America/New_York', with a matching minute offset and a plausible navigator.language.
What a detector infers
This check reads `Intl.DateTimeFormat().resolvedOptions().timeZone` and records it alongside `-new Date().getTimezoneOffset()` and `navigator.language`. It passes as long as a non-empty zone string comes back, and it is 'info' severity — contextual, not scored. Its value is as a baseline reading rather than a verdict: the resolved zone is the anchor that the offset-coherence check compares against, and it is the signal a detector cross-references with IP geolocation and Accept-Language. An empty or unresolvable zone is unusual enough on its own to be worth surfacing, since real consumer browsers always resolve a named zone from the host ICU data.
How to resolve it
Nothing to fix if a zone resolves — this line is informational context for the timezone coherence checks below it. If it reads 'n/a', the ICU/timezone data in the environment is missing or Intl has been tampered with; restore a normal ICU build rather than stubbing Intl.
Read in the wild by
Kasada
Collects both the numeric UTC offset — via new Date().getTimezoneOffset(), called once per realm object so the page and the iframe are read separately — and the resolved zone string, via Intl.DateTimeFormat().resolvedOptions() on globalThis.
2.txt:10505 `r2 = r5.getTimezoneOffset()` on `a0["efg"]` and 2.txt:23874 on `a0["lbg"]` — two distinct realm objects (same 2-site pattern at 1.txt:2072/45872, 3.txt:2278/47389); 2.txt:9771 `globalThis.Intl.DateTimeFormat()` → 9775 `.resolvedOptions()`, entries kept unfiltered (exclusion list `_2585` is empty), so the resolved timeZone string is included; probes.txt: window_timezone_offset, window_timezone_string, iframe_timezone_offset, iframe_timezone_string
PerimeterX / HUMAN
Resolves `Intl.DateTimeFormat().resolvedOptions().timeZone` and ships the IANA zone name in its encrypted payload, recording the literal "undef" when the lookup throws.
PerimeterX collector `main.min.js` (ifood tenant, /root/re/PerimeterX_RE/stample/ifood/source/main.min.js), function `xp(t)`: `try{var n=hS[hQ(357)][hQ(358)]();t[hQ(359)]=n.resolvedOptions()[hQ(360)]}catch(n){t["UT0kdxRdI0Y="]="undef"}` — where the bundle's string table resolves hQ(357)='Intl', hQ(358)='DateTimeFormat', hQ(359)='UT0kdxRdI0Y=', hQ(360)='timeZone'. The value ships in the EV2 payload as `"UT0kdxRdI0Y=": "Asia/Shanghai"`. Corroborated in a second tenant bundle (totalwine) where the same probe appears under a rotated key: `try{var t=ip[im(368)][im(369)]();i["AEwzBkUsMjc="]=t.resolvedOptions().timeZone}catch(t){i["AEwzBkUsMjc="]=im(370)}`.
CreepJS
CreepJS, an open-source research and education demo rather than a production detector, reads the IANA zone from Intl.DateTimeFormat().resolvedOptions() and uses it two ways in its timezone section: as the reported location, and as the reference value that a zone it re-derives independently from historical offset probing is compared against.
creepjs, src/timezone/index.ts (master), inside the timezone test's returned `data` object — L554: `const { timeZone } = Intl.DateTimeFormat().resolvedOptions()`; L555: `const decrypted = decryptLocation({ year, timeZone })`; L560: `location: formatLocation(timeZone),`; L563: `offset: new Date().getTimezoneOffset(),`. Corroborating, L548 lists `Intl.DateTimeFormat.resolvedOptions` among the APIs whose tampering sets the section's `lied` flag.
Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Environment & locale
- timezone is not UTC
timezone-not-utcThe check resolves the Intl zone and fails only when it is exactly 'UTC' or 'Etc/UTC'. - IANA zone offset matches the JS clock offset (incl. across DST)
timezone-offset-coherenceThis is a two-source cross-check on the same fact. It takes the resolved IANA zone, formats the current instant through Intl.DateTimeFormat… - navigator.plugins is consistent with the PDF viewer
has-pluginsAn empty navigator.plugins is only meaningful when it contradicts something else, and this check is written to respect that. - navigator.pdfViewerEnabled is true
pdf-viewerA direct read of navigator.pdfViewerEnabled. It is N/A when the property is not exposed at all, passes when true, and is marked false… - mimeTypes are consistent with navigator.plugins
plugins-mimetypesThis walks navigator.mimeTypes, and for each entry reads .enabledPlugin and checks that the exact object is present in a Set built from… - proprietary codecs (H.264 / AAC) present for a Chrome UA
codec-supportThe check calls canPlayType on a video and audio element for H.264 ('avc1.42E01E') and AAC ('mp4a.40.2'), plus MP4/WebM/Ogg for context, and… - Blink-only Web APIs present for a Chrome UA
blink-web-apisWhen the UA matches Chrome/\d+ and the page is a secure context, this probes four Blink-only surfaces: navigator.connection… - CSS feature support matches the engine (Blink for a Chrome UA)
css-engine-surfaceFor any UA containing 'Chrome/', this requires CSS.supports('-webkit-app-region', 'drag') to be true and the Gecko markers — MozAppearance…
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Environment & locale checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Environment & locale — the family timezone-present belongs to.