Chrome 67历史时区变更问题求助:日期时区计算异常
Hey there, I get how frustrating this sudden cross-browser inconsistency can be—let's work through this without having to rewrite all your code!
What's causing the issue?
Chrome 67 updated its underlying IANA timezone database to reflect historical timezone changes more accurately. Back in 1900, Moscow's official timezone was actually UTC+02:30, not UTC+03:00. Other browsers (Edge, IE, Firefox at the versions you tested) haven't updated their historical timezone data yet, which is why you're seeing the mismatch.
Solutions to fix this:
1. Use UTC dates for consistent results (simplest fix)
If your business logic doesn't require precise historical timezone calculations, switch to UTC dates to avoid browser-specific differences. For example:
// Create a UTC date instead of relying on local timezone parsing const utcDate = new Date(Date.UTC(1900, 0, 1, 0, 0, 0)); console.log(utcDate.getTimezoneOffset()); // Will return 0 for all browsers
You can also append a Z to your date strings to explicitly mark them as UTC:
new Date("1900-01-01T00:00:00Z").getTimezoneOffset(); // Returns 0 across all browsers
2. Use a dedicated date/time library (most reliable fix)
For cases where you need accurate historical timezone handling across all browsers, use a library that maintains comprehensive timezone data. Moment Timezone or Luxon are solid choices:
Using Moment Timezone:
// Specify the timezone explicitly to get consistent results const moscowDate = moment.tz("1900-01-01T00:00:00", "Europe/Moscow"); console.log(moscowDate.utcOffset()); // Returns -150 (UTC+02:30) consistently across browsers
Using Luxon:
const { DateTime } = luxon; const moscowDate = DateTime.fromISO("1900-01-01T00:00:00", { zone: "Europe/Moscow" }); console.log(moscowDate.offset); // Returns 150 (minutes ahead of UTC) consistently
These libraries handle historical timezone rules uniformly, so you won't run into browser-specific discrepancies.
3. Browser-specific fallback (not recommended long-term)
If you need a quick temporary fix without adding a library, you can detect Chrome 67+ and adjust the offset manually for affected dates. Note that this is fragile—browser timezone data may update again in the future:
function getAdjustedTimezoneOffset(date) { const isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); const chromeVersion = parseInt(navigator.userAgent.match(/Chrome\/(\d+)/)[1], 10); // Check if it's Chrome 67+ and the date falls in the affected historical range if (isChrome && chromeVersion >= 67 && date.getFullYear() === 1900) { // Adjust to match other browsers' current behavior return -180; } return date.getTimezoneOffset(); } // Usage example console.log(getAdjustedTimezoneOffset(new Date("1900-01-01T00:00:00")));
Final Takeaway
You don't need to rewrite all your code! The best approach depends on your needs: use UTC for simple consistency, or a dedicated library for accurate historical timezone handling. The browser-specific fallback should only be a short-term stopgap.
内容的提问来源于stack exchange,提问作者Alexey

