Have you ever called Intl.DateTimeFormat().resolvedOptions().timeZone in your browser, compared it with an IP-geolocation-based "my timezone" result, and gotten two different answers?
Neither answer is wrong. They answer two different questions. Here is how they differ, why a mismatch is usually normal, and why a bare UTC offset is never enough to define a timezone.
Your browser timezone: what your OS claims
When JavaScript asks for your time zone, it doesn't ask the network — it asks the operating system:
const { timeZone } = Intl.DateTimeFormat().resolvedOptions();
console.log(timeZone); // e.g. "Asia/Shanghai"
Intl.DateTimeFormat().resolvedOptions().timeZone returns an IANA time zone identifier (like Asia/Shanghai, America/New_York, or Europe/Berlin) taken from the OS settings. It is free, instant, and privacy-friendly — but only as accurate as the machine's own configuration.
Your IP timezone: what your exit IP suggests
An "IP timezone" is estimated from your egress IP address via a GeoIP database. It answers a completely different question: where does the internet think your connection comes out?
These two can legitimately disagree:
-
VPN / proxy / corporate egress — your browser reports
Asia/Taipei, but your traffic exits in Frankfurt, so the IP-based estimate saysEurope/Berlin. - Remote desktop / cloud VM — the OS belongs to a machine on another continent.
- Manually changed system timezone — developers do this all the time to test scheduling logic.
- Stale or coarse GeoIP data — IP-to-location mappings are estimates, and they shift.
So when the two answers differ, it is not necessarily a bug on either side. It is a signal worth understanding — especially if your app relies on it for scheduling, logging, or analytics.
UTC offset ≠ time zone identifier
This is the part that bites developers most often. An offset like "UTC+8" is a snapshot, not an identity. "How many hours apart are two time zones?" is a question that only makes sense with a date attached, because daylight saving time shifts offsets through the year.
Take America/New_York: it is UTC-5 in January and UTC-4 in July. Hard-coding -5 will be wrong for half the year.
And the three-letter abbreviations are a trap. CST can mean at least three different things:
- China Standard Time — UTC+8, no DST, all year
- US Central Standard Time — UTC-6, switching to CDT (UTC-5) in summer
- Cuba Standard Time — UTC-5, with its own DST rules
"PST" is no better (US Pacific vs. Philippine Standard Time, which is UTC+8 and observes no DST). Always use IANA identifiers like Asia/Shanghai or America/Chicago in code, APIs, and databases — never bare abbreviations.
A free tool that makes all of this visible
I came across a free timezone tool that puts these concepts into practice. Everything is computed locally in the browser — no location permission prompts, no data uploaded:
What it does:
- Browser timezone, instantly — shows the IANA identifier your browser reports, the current UTC offset, and whether DST is active.
- IP timezone, one click — estimates your timezone from your egress IP and puts it side-by-side with the browser timezone (it never displays your IP address). Great for a quick VPN egress check.
- Time difference calculator — pick any two IANA time zones and get the offset for today, mid-January, and mid-July, with DST handled automatically. The "bring a date, not just an offset" principle, built in.
- China reference table — China vs. Germany, Japan, New York, Los Angeles, the UK, France, Toronto, and Sydney at a glance.
- Timezone knowledge FAQ — UTC vs. GMT, ambiguous abbreviations (CST/PST), why China uses a single legal time zone, and the story of Xinjiang's Ürümqi time.
Takeaways
-
Intl.DateTimeFormat().resolvedOptions().timeZoneis your OS's answer; IP geolocation is your network's answer. Expect them to differ sometimes. - Offsets need dates. Use IANA identifiers, not "UTC+8" or "CST".
- When in doubt, open the tool above and compare: browser time, the IP-based estimate, and the DST-aware difference calculator.
Top comments (0)