Intl.DateTimeFormat Timezone Consistency for Proxied Profiles
Say your team runs geo QA for a client. The profile uses a Tokyo proxy, and the landing page shows Japanese pricing and a Japanese cookie banner. Then someone opens the console and sees America/Denver where Asia/Tokyo should be. The IP says one place, the browser says another, and the page you are testing may now be reacting to the browser's answer.
The cause is usually an update or a setting that quietly changed how Intl.DateTimeFormat().resolvedOptions().timeZone is reported. The old value matched the proxy's IANA timezone. The new one fell back to the system timezone. Meanwhile getTimezoneOffset() kept returning the configured offset, and many checker pages only show the offset, so nothing looked wrong.
That is the inconsistency this guide is about. It is a single JavaScript call, and it fails silently. Your profile looks fine until a page localises on the wrong signal.
What We're Building
By the end of this tutorial, you'll understand:
- How
Intl.DateTimeFormat().resolvedOptions().timeZoneworks at the resolution level - Why it exposes misconfigurations that offset checks miss
- How to verify consistency between IANA timezone, Date offset, proxy geolocation, and Accept-Language
- How to configure JustBrowser profiles so those values agree automatically
You'll have a verification workflow that catches timezone mismatches before a client or a reviewer does.
Prerequisites
- JustBrowser installed (the 7-day trial is full access, which is all this needs)
- At least one profile with a proxy configured
- A working proxy where you know the expected location (country and city)
- 15 minutes
- Basic comfort with browser DevTools console
If you haven't set up proxies yet, the ISP proxy setup tutorial covers the basics. This guide assumes you have a proxied profile ready to test.
Step 1: Understand What Intl.DateTimeFormat Actually Returns
Most people think timezone configuration means setting getTimezoneOffset(). That is not enough.
getTimezoneOffset() returns minutes from UTC. A user in California in January returns 480 (UTC-8). A user in Tokyo returns -540 (UTC+9). Simple number.
But Intl.DateTimeFormat().resolvedOptions().timeZone returns the full IANA timezone identifier:
Intl.DateTimeFormat().resolvedOptions().timeZone
// Returns: "America/Los_Angeles" or "Asia/Tokyo" or "Europe/Berlin"
Much more specific. UTC-8 could be:
- America/Los_Angeles (California)
- America/Vancouver (British Columbia)
- America/Tijuana (Mexico)
- Pacific/Pitcairn (tiny island, seriously)
Websites that localise content, analytics tools and fraud-prevention systems read the IANA string because it identifies a region, not just an offset band. When a site compares it with the location of your proxy's IP, it is checking whether the two agree. A Tokyo proxy returning "America/Denver" is a plain contradiction, and your test results reflect a visitor who doesn't exist. For context on how large ad platforms treat browser signals, see our Facebook fingerprinting breakdown.
The second requirement: the two browser values have to agree with each other. If Intl.DateTimeFormat says "America/New_York" but getTimezoneOffset() returns 480 (Pacific time), something is broken. Real browsers don't have this contradiction.
Step 2: The DST Problem (Where Static Configs Break)
America/New_York means:
- UTC-5 (EST) from November to March
- UTC-4 (EDT) from March to November
If a tool stores the offset as a static value, say 300 for Eastern, it is correct half the year and wrong the other half. A profile configured in January with offset 300 will report the wrong offset in July.
A page can check this dynamically. It knows today's date and the DST rules for the claimed IANA timezone, so it can compute the offset that should be reported:
// Consistency check (simplified)
const claimedTz = Intl.DateTimeFormat().resolvedOptions().timeZone;
const reportedOffset = new Date().getTimezoneOffset();
const expectedOffset = computeExpectedOffset(claimedTz, new Date());
// computeExpectedOffset uses IANA database rules
if (reportedOffset !== expectedOffset) {
console.warn("TIMEZONE_OFFSET_MISMATCH");
}
This is why "set and forget" offsets break. DST transitions happen twice a year, and a multi-account browser that doesn't derive the offset from the IANA zone leaves profiles inconsistent twice a year. You probably won't notice until a test result looks odd.
JustBrowser computes the offset from the IANA timezone dynamically on each query. It isn't cached or static: it is computed fresh with DST rules applied to the current date. Our multi-account browser myths post covers how different tools approach profile settings.
Step 3: Cross-Check Against Proxy Geolocation
Now add the proxy. Your proxy IP geolocates to a specific place via MaxMind, IP2Location, or similar databases. Sites query these databases too, or use their own.
The consistency check:
- IP geolocation → Berlin, Germany
- Intl.DateTimeFormat timezone → should be Europe/Berlin
- getTimezoneOffset → should be -60 (CET) or -120 (CEST) depending on date
- Accept-Language → should have de or de-DE somewhere prominent
If your proxy geolocates to Berlin but your IANA timezone says America/Chicago, the page gets conflicting answers about where the visitor is. Real users in Berlin have the Europe/Berlin timezone. Edge cases such as expats who never changed their laptop settings exist, but for a geo test you want the common case.
Residential proxies can geolocate inconsistently. Your provider says "Germany" but MaxMind says "Netherlands." Or the IP moved, because residential IPs churn. Before blaming the profile configuration, verify where your proxy actually geolocates.
Run your proxy IP through:
JustBrowser's built-in proxy tester also reports the exit IP, country, city and timezone. Note the actual reported location. That is the location you need to match, not what your proxy provider claims.
Step 4: Verify Accept-Language Consistency
This one adds to the signal. It isn't decisive alone, but a page may choose language and currency from it.
navigator.language // Primary language: "de-DE"
navigator.languages // Full list: ["de-DE", "de", "en-US", "en"]
A German user typically has German first. An American user has English first. A Japanese user has Japanese first. Not always, since multilingual users exist, but primary language correlates strongly with location.
A Berlin proxy plus Europe/Berlin timezone plus en-US primary language is possible, but for a market test it may show you an English page instead of the German one. For profiles meant to show what a local visitor sees, match the language:
| Proxy Location | Recommended Primary Language | Secondary Languages |
|---|---|---|
| Germany | de-DE | de, en-US, en |
| Japan | ja-JP | ja, en-US, en |
| Brazil | pt-BR | pt, en-US, en |
| France | fr-FR | fr, en-US, en |
| United States | en-US | en |
| United Kingdom | en-GB | en, en-US |
It is a lot of table, but setting these is quick once you have a template. If your team manages many client accounts it is allowed to hold, the multi-account guide covers language settings as part of profile hygiene.
The secondary languages matter too. A German user who speaks English might have en as a fallback. Having zh-CN as secondary when your proxy is in Berlin is possible, but it probably isn't what you meant to test.
Step 5: Configure JustBrowser for Consistency
Open your profile in JustBrowser. We're going to align all four signals.
Timezone Configuration:
- Go to Fingerprint Settings → Timezone
- Set to Auto-detect from proxy
- This does two things: pulls the IANA timezone from your proxy's geolocated region AND computes the correct offset for today's date with DST applied
Language Configuration:
- Go to Fingerprint Settings → Language
- Set primary language to match your proxy region (see table above)
- Add English as secondary (most profiles benefit from this)
- JustBrowser will set both
navigator.languageand the Accept-Language header
Geolocation API:
- Go to Network Settings → Geolocation
- Set it to block requests, or to report the proxy's location
- This keeps your real GPS/WiFi location from being exposed through
navigator.geolocation
Step 6: Test the Configuration
Don't assume it works. Verify, every time you change a proxy or update the app.
Console Check:
Open browser DevTools (F12) and run:
// IANA timezone
console.log("Timezone:", Intl.DateTimeFormat().resolvedOptions().timeZone);
// Offset in minutes (negative = ahead of UTC)
console.log("Offset:", new Date().getTimezoneOffset());
// Languages
console.log("Language:", navigator.language);
console.log("Languages:", navigator.languages);
Verify:
- Timezone matches your proxy's region
- Offset is correct for that timezone TODAY (check DST)
- Language matches the region
Cross-Check Tool:
BrowserLeaks (https://browserleaks.com) is useful here. Run the full test, then compare the JavaScript section (timezone) with the IP section (geolocation). They should align.
If you're running ad verification workflows through these profiles, timezone consistency matters. Ad platforms compare geo-targeting against the visitor's detected location, so a profile that disagrees with itself can show you ads, or no ads, for the wrong market and defeat the purpose of the check.
Common Errors and Fixes
Error: IANA timezone shows as "UTC" or "Etc/UTC"
Cause: The profile couldn't determine timezone from proxy, defaulted to UTC.
Fix: Check that your proxy is active and geolocating correctly. Manually set the IANA timezone to match your proxy's location if auto-detect fails.
Error: Timezone correct but offset wrong
Cause: DST mismatch. The offset is stale, set during a different time of year.
Fix: If using manual configuration, update the offset. If using auto-detect, restart the profile. The offset should recompute on launch.
Error: navigator.language doesn't change after configuration
Cause: Profile wasn't fully closed before relaunching.
Fix: Close the profile completely in JustBrowser (not just the browser window). Relaunch. Language settings apply on fresh launch.
Error: A checker shows a mismatch but BrowserLeaks doesn't
Cause: Some pages compare the offset against the IANA zone with DST rules. BrowserLeaks mostly displays what the browser reports.
Fix: Trust the stricter check. If it reports a mismatch, the mismatch is real. Our TLS fingerprint guide explains what else a server can see.
Error: Everything checks out but the page still behaves differently
Cause: Timezone consistency is necessary but not the only input. Other signals, such as TLS characteristics, language, cookies and the reputation of the IP, also shape what a site shows.
Fix: Timezone is one layer. Verify the other layers separately. The JA4 TLS fingerprint guide covers TLS-level details. IP quality matters too: a proxy IP with a poor reputation will be treated differently whatever the browser reports. For ad verification use cases, ClickzProtect's approach shows how a site owner combines multiple signals.
Next Steps
With timezone consistent, one common source of confusing test results is gone. It isn't the only one, since browser identity is a multi-layered topic, but it is an easy one to check.
If your team also needs email on its own domains alongside client account management, JustEmails provides custom-domain mailboxes. Different product, same principle: DNS and mail settings that disagree cause odd results.
For automation workflows via Playwright or Puppeteer, the REST API guide shows how to start profiles with their timezone config applied programmatically. No manual setup per profile.
And if you're tracking conversions from multi-account campaigns, JustAnalytics provides analytics without adding extra fingerprinting signals to your tested profiles.
The IANA timezone string is one line of JavaScript. Most teams never check it:
Intl.DateTimeFormat().resolvedOptions().timeZone
It takes a moment to query, and it is the difference between a geo test that reflects the market you meant to test and one that doesn't.
Check yours.
Frequently Asked Questions
Why is Intl.DateTimeFormat().resolvedOptions().timeZone more specific than getTimezoneOffset()?
getTimezoneOffset() only returns minutes from UTC, so UTC-8 could be America/Los_Angeles, America/Vancouver, or America/Tijuana. Intl.DateTimeFormat().resolvedOptions().timeZone returns the full IANA identifier like 'America/Los_Angeles'. Sites that localise content use the IANA string because it pins a visitor to a specific region, not just an offset. Two users in the same offset but different cities have different IANA timezones, which is why a geo test needs the identifier and not only the number.
What happens when timezone and offset don't match due to DST?
A browser reporting America/New_York should return 300 (UTC-5) in winter and 240 (UTC-4) in summer. If a profile's offset was fixed at 300 in January and you are still using it in July, the offset is wrong by an hour. Pages that compute the expected offset for the reported timezone on today's date will see the mismatch, and your test will show times that no real visitor would see. It means either a stale configuration or a timezone that isn't being computed from the IANA rules.
Can Accept-Language headers show a mismatch with the timezone?
Not directly, but they add to it. A Japanese proxy with Asia/Tokyo timezone but en-US as the primary Accept-Language gives a page two different answers about where the visitor is. For a localisation test that matters, because the site may pick the language, currency or banner from either signal. Align timezone, language and proxy location so the test shows what a visitor in that market sees.
How do I test whether my Intl.DateTimeFormat setting is working?
Open the browser console and run: Intl.DateTimeFormat().resolvedOptions().timeZone. That gives you the IANA string. Then run: new Date().getTimezoneOffset(). Compute the expected offset for your IANA timezone on today's date (accounting for DST). They should match. Finally, check navigator.language and navigator.languages, where the primary language should be plausible for the timezone region. Any mismatch means the profile needs reconfiguration.
Try JustBrowser
Native Chromium multi-account browser for teams, not extension-based. Real C++ engine patches at the canvas / WebGL / audio / font / screen layer, across 40+ identity parameters. Local REST API + CDP for Playwright, Puppeteer, Selenium. $9.99/month or $99.99/year. 7-day free trial, card required — cancel any time in the seven days and you are not charged. Unlimited profiles.
Get started → · How it differs from Multilogin / GoLogin / AdsPower
Ready to manage multiple accounts?
Seven days free, then $9.99/month — one plan, everything included.