Closed Bug 1330307 Opened 8 years ago Closed 6 years ago

Intl.DateTimeFormat formats the date in the wrong timezone in some cases

Categories

(Core :: JavaScript: Internationalization API, defect, P3)

50 Branch
defect

Tracking

()

RESOLVED DUPLICATE of bug 1346211

People

(Reporter: levdmitriy, Unassigned)

References

Details

User Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 Steps to reproduce: 1. Change system time zone to the Moscow (UTC +3:00). I also reproduce it with (UTC +4:00) Baku 2. Just open https://jsfiddle.net/9ygfq19n/ or run in the console: var options = { hour: "numeric", minute: "numeric" }; var dateTimeFormat = new Intl.DateTimeFormat('en-US', options); dateTimeFormat.format(new Date('2012/05/14 12:13:14')); Actual results: 1:13 PM Expected results: 12:13 PM If you change system time zone to any other (I've tried (UTC +4) Tbilisi) - all OK
Component: Untriaged → JavaScript Engine
Product: Firefox → Core
Component: JavaScript Engine → JavaScript: Internationalization API
This is an issue with Windows' localtime_s function (which we use in js/src/vm/DateTime.cpp). Simple repro: --- #include <ctime> #include <iostream> using namespace std; static bool ComputeLocalTime(time_t local, struct tm* ptm) { #if defined(_WIN32) return localtime_s(ptm, &local) == 0; #else return localtime_r(&local, ptm); #endif } int main() { struct tm tm{}; if (!ComputeLocalTime(static_cast<time_t>(1336982400), &tm)) return 0; cout << "hour: " << tm.tm_hour << endl; return 0; } --- This should print "hour: 12", but instead prints "hour: 11" on Windows (tested on Win10).
This seems to be a bug with daylight savings time (in 2012 which is used in comment 0, Russia used permanent DST). Example: var monthFormat = new Intl.DateTimeFormat("en-US", { month: "short" }).format; var dateTimeFormat = new Intl.DateTimeFormat("en-US", { year: "numeric", month: "short", day: "numeric", hour: "numeric" }).format; var output = ""; for (var month = 0; month < 12; month++) { //output += new Date(0, month) + "\n"; var date = new Date(0, month); output += date + " - " + dateTimeFormat(date) + "\n"; } output generates the following output on Windows (8.1): /* Mon Jan 01 1900 00:00:00 GMT+0100 - Jan 1, 1900, 12 AM Thu Feb 01 1900 00:00:00 GMT+0100 - Feb 1, 1900, 12 AM Thu Mar 01 1900 00:00:00 GMT+0100 - Mar 1, 1900, 12 AM Sun Apr 01 1900 00:00:00 GMT+0200 - Mar 31, 1900, 11 PM Tue May 01 1900 00:00:00 GMT+0200 - Apr 30, 1900, 11 PM Fri Jun 01 1900 00:00:00 GMT+0200 - May 31, 1900, 11 PM Sun Jul 01 1900 00:00:00 GMT+0200 - Jun 30, 1900, 11 PM Wed Aug 01 1900 00:00:00 GMT+0200 - Jul 31, 1900, 11 PM Sat Sep 01 1900 00:00:00 GMT+0200 - Aug 31, 1900, 11 PM Mon Oct 01 1900 00:00:00 GMT+0200 - Sep 30, 1900, 11 PM Thu Nov 01 1900 00:00:00 GMT+0100 - Nov 1, 1900, 12 AM Sat Dec 01 1900 00:00:00 GMT+0100 - Dec 1, 1900, 12 AM */ On Linux, I and Mac user Wawuschel get: /* Mon Jan 01 1900 00:00:00 GMT+0100 (CET) - Jan 1, 1900, 12 AM Thu Feb 01 1900 00:00:00 GMT+0100 (CET) - Feb 1, 1900, 12 AM Thu Mar 01 1900 00:00:00 GMT+0100 (CET) - Mar 1, 1900, 12 AM Sun Apr 01 1900 00:00:00 GMT+0100 (CET) - Apr 1, 1900, 12 AM Tue May 01 1900 00:00:00 GMT+0100 (CET) - May 1, 1900, 12 AM Fri Jun 01 1900 00:00:00 GMT+0100 (CET) - Jun 1, 1900, 12 AM Sun Jul 01 1900 00:00:00 GMT+0100 (CET) - Jul 1, 1900, 12 AM Wed Aug 01 1900 00:00:00 GMT+0100 (CET) - Aug 1, 1900, 12 AM Sat Sep 01 1900 00:00:00 GMT+0100 (CET) - Sep 1, 1900, 12 AM Mon Oct 01 1900 00:00:00 GMT+0100 (CET) - Oct 1, 1900, 12 AM Thu Nov 01 1900 00:00:00 GMT+0100 (CET) - Nov 1, 1900, 12 AM Sat Dec 01 1900 00:00:00 GMT+0100 (CET) - Dec 1, 1900, 12 AM */
Status: UNCONFIRMED → NEW
Ever confirmed: true
I got Mon Jan 01 1900 00:00:00 GMT+0300 - Jan 1, 1900, 6 AM Thu Feb 01 1900 00:00:00 GMT+0300 - Feb 1, 1900, 6 AM Thu Mar 01 1900 00:00:00 GMT+0300 - Mar 1, 1900, 6 AM Sun Apr 01 1900 00:00:00 GMT+0300 - Apr 1, 1900, 6 AM Tue May 01 1900 00:00:00 GMT+0300 - May 1, 1900, 6 AM Fri Jun 01 1900 00:00:00 GMT+0300 - Jun 1, 1900, 6 AM Sun Jul 01 1900 00:00:00 GMT+0300 - Jul 1, 1900, 6 AM Wed Aug 01 1900 00:00:00 GMT+0300 - Aug 1, 1900, 6 AM Sat Sep 01 1900 00:00:00 GMT+0300 - Sep 1, 1900, 6 AM Mon Oct 01 1900 00:00:00 GMT+0300 - Oct 1, 1900, 6 AM Thu Nov 01 1900 00:00:00 GMT+0300 - Nov 1, 1900, 6 AM Sat Dec 01 1900 00:00:00 GMT+0300 - Dec 1, 1900, 6 AM on Win7. Is the latest timezone update applied? (In reply to Sebastian Hengst [:aryx][:archaeopteryx] (needinfo on intermittent or backout) from comment #2) > Mon Jan 01 1900 00:00:00 GMT+0100 - Jan 1, 1900, 12 AM Why GMT+0100? did you change the timezone before testing?
https://tc39.github.io/ecma402/#sec-tolocaltime > If the calendar is "gregory", then the calculations must match the algorithms specified in ES2017, 20.3.1. Hm, then this is definitely a bug of the Windows implementation.
(In reply to Masatoshi Kimura [:emk] from comment #3) > Is the latest timezone update applied? Yes (using Windows 8.1 and no updates offered). > (In reply to Sebastian Hengst [:aryx][:archaeopteryx] (needinfo on > intermittent or backout) from comment #2) > > Mon Jan 01 1900 00:00:00 GMT+0100 - Jan 1, 1900, 12 AM > > Why GMT+0100? did you change the timezone before testing? I kept my local time because I stumbled upon this bug in bug 1331608.
Note, there's a related open spec question at https://github.com/tc39/ecma262/pull/778 . The logic of timezones that's referenced by local dates in the Date constructor doesn't handle historical timezone changes well. It is based on a single timezone offset from GMT, with only the DST offset being based on the current time. By contrast, ICU does handle the historical changes well. I think this is a factor in mismatches here generally. You'll find a similar mismatch in V8 and JSC, reproducible on Linux as well.
Blocks: 285663
Priority: -- → P3
Dup'ing forward to bug 1346211 which should have fixed this problem. Please reopen if the issue is still present. Thanks!
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.