← All articles

Timezone and locale consistency, the most common self-inflicted tell

5 min read fingerprintingtimezonelocaleguide

Routing traffic through a proxy changes one thing: the IP address a server sees. It changes nothing about the operating system underneath the browser, which keeps reporting its own timezone, its own language, and its own locale formatting exactly as configured. A session claiming a residential IP in one country while its clock, language, and number formatting all belong to another is not a subtle signal. It is arguably the single cheapest check available to any site, and it needs no fingerprinting script at all to catch.

Every place the timezone leaks

Every place the locale leaks

Geolocation, if it is granted

navigator.geolocation.getCurrentPosition() requires an explicit permission prompt, so it is not always available, but when a user accepts it the coordinates it returns need to fall inside the same country the IP address geolocates to and the same timezone the clock reports. Three independent signals agreeing is a much stronger claim than any one of them alone, which is exactly why sites that get the permission tend to check it against the other two rather than trusting it in isolation.

The check that needs no JavaScript at all

A server can catch a mismatch without ever running a fingerprinting script, using only its own request log. It looks up the source IP's country and typical UTC offset in a geoIP database, then compares that against any timestamp the client already sent for an unrelated reason, such as a cookie-consent banner's recorded local time, an order form's local time field, or the client clock value in a websocket handshake. If the IP geolocates to a timezone eight hours off UTC but the client-supplied timestamp implies a clock five hours off UTC, that gap exists in plain log data, no script property required. This is why a proxy change alone, with the operating system left on its own time and language settings, is such a common and easy failure.

Checklist

Binding a proxy to a profile makes timezone, locale, and geolocation follow the exit IP automatically, which removes the step where this usually goes wrong: someone changes the proxy for a session and forgets that nothing else in the stack moved with it.

Where a free, simpler fix is the right answer

If you only need to preview a page once as if you were in another timezone, Chrome DevTools' Sensors panel already overrides geolocation for free, and your operating system's own locale and timezone settings, changed for the session, cover the rest of a one-off manual check. Neither needs a separate browser profile or any proxy at all. What that approach does not solve is keeping many persistent identities each internally consistent across restarts, weeks apart, without you remembering to re-check six properties by hand every time. That is a different, ongoing problem from previewing one page once, and it is worth being honest about which one you actually have before reaching for anything heavier.

Verify it yourself

function localeReport() {
  return {
    timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    offsetMinutes: new Date().getTimezoneOffset(),
    dateString: new Date().toString(),
    language: navigator.language,
    languages: navigator.languages,
    numberSample: new Intl.NumberFormat().format(1234567.89),
  }
}
console.log(localeReport())

Compare the timeZone and offsetMinutes fields against where your exit IP actually is, for example with any IP-lookup site, and compare language against the Accept-Language header your browser sends, visible in your network devtools on any request. For the exit IP side of this problem, see residential versus datacenter proxies, and for the fuller list of properties that need to agree with each other beyond timezone and locale, the fingerprint consistency checklist.

Try it on the free tier.

Unlimited local profiles, no credit card. Check it against the detectors yourself.