Closed Bug 1655947 Opened 5 years ago Closed 5 years ago

JavaScript Date parses strings incorrectly after 2020-07-20

Categories

(Core :: JavaScript: Standard Library, defect, P2)

79 Branch
defect

Tracking

()

RESOLVED FIXED
82 Branch
Tracking Status
firefox-esr78 --- wontfix
firefox81 --- wontfix
firefox82 --- fixed

People

(Reporter: feedbro.reader, Assigned: avandolder)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0

Steps to reproduce:

Try this in the browser's JavaScript console:

  1. new Date("Mon, 20 Jul 20 13:00:28 +0200");
    -> it returns correctly Date object Date Mon Jul 20 2020 14:00:28

now try this:
2. new Date("Tue, 21 Jul 20 13:00:28 +0200");
-> it returns INCORRECTLY Date object Date Tue Jul 20 2021 14:00:28 GMT+0300

now try this:
3. new Date("Wed, 29 Jul 20 13:00:28 +0200");
-> it returns INCORRECTLY Date object Date Fri Jul 20 2029 14:00:28 GMT+0300

now try this:
4. new Date("Mon, 31 Aug 20 13:00:28 +0200");
-> it returns INCORRECTLY Date object ate Wed Aug 20 2031 14:00:28 GMT+0300

Seems like the day of the month starts to define the year in the Date object?

Actual results:

see above

Expected results:

dates should be parsed correctly. These work fine on Chromium based browsers.

In case someone is wondering where are these coming from, this feed uses this 2-digit year format: https://rekordcenturion.co.za/rss-output/

Chrome-variants seem to consistently parse those date stamps so that the first number after the day name (e.g. Mon) is the day of the month but Firefox seems to interpret that number as the year?

I'm not really sure what's the correct behavior here?

Looks like new Date("Sun, 19 Jul 20 13:00:00") still works and returns Date object Date Sun Jul 19 2020 13:00:00 GMT+0300 (Eastern European Summer Time).

So 2020-07-20 is the date after which things start to go haywire.

Bugbug thinks this bug should belong to this component, but please revert this change in case of error.

Component: Untriaged → JavaScript: Standard Library
Product: Firefox → Core
Blocks: 1274354

(In reply to voltron from comment #1)

I'm not really sure what's the correct behavior here?

Unfortunately there's no correct behaviour for this case. The ECMAScript specification only defines how to handle a restricted set of formats and everything else implementation-defined.

(In reply to André Bargull [:anba] from comment #4)

(In reply to voltron from comment #1)

I'm not really sure what's the correct behavior here?

Unfortunately there's no correct behaviour for this case. The ECMAScript specification only defines how to handle a restricted set of formats and everything else implementation-defined.

The main problem here is that the interpretation changes "in flight". So before 2020-07-20 it works differently than after it. So whatever the implementation is, it should be at very least consistent across all date spans?

Looks like that switching (first number is interpreted as a year in some conditions and as a day of month in others) is intentionally implemented which is beyond me. Why on earth would anyone want it to work like that?

Starting on line 1384:
https://dxr.mozilla.org/mozilla-central/source/js/src/jsdate.cpp

I think case b) should not exist because the comments say "mon, mday and year values are adjusted to achieve Chrome compatibility" but AFAIK Chrome does not work that way with any input.

I can reproduce this bug in the devtools console as follow:

new Date("19 Jul 20") // = Date Sun Jul 19 2020 00:00:00 GMT+0200 (Central European Summer Time)
new Date("20 Jul 20") // = Date Mon Jul 20 2020 00:00:00 GMT+0200 (Central European Summer Time)
new Date("21 Jul 20") // = Date Tue Jul 20 2021 00:00:00 GMT+0200 (Central European Summer Time)
Severity: -- → S3
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P2

My guess is that the issue comes from here:
https://searchfox.org/mozilla-central/source/js/src/jsdate.cpp#1399-1403

The good news is that it would be fixed in 11 years.

André, any idea how to fix that sooner?

Flags: needinfo?(andrebargull)

It looks like what Chrome does is more like this:

-    if (year > 0 && (mday == 0 || mday > year) && !seenFullYear) {
+    if (year > 0 && (mday == 0 || mday > 31) && !seenFullYear) {

This seems like an improvement at the margin. Ultimately we need to either (a) take the time to specify something web-compatible and reasonably well-behaved; or (b) do exactly what Chrome does.

Chrome's implementation looks reasonable so +1 for that.

(In reply to Nicolas B. Pierron [:nbp] from comment #8)

André, any idea how to fix that sooner?

The change in comment #9 should fix it.

Flags: needinfo?(andrebargull)
Assignee: nobody → avandolder
Status: NEW → ASSIGNED
Pushed by avandolder@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/61f829bdf508 Change date parsing to be more consistent. r=jorendorff
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → 82 Branch

This seems ESR uplift worthy...

Are you going to request the uplift? thanks

Flags: needinfo?(mozilla)

Probably a question for Jason.

Flags: needinfo?(mozilla) → needinfo?(jorendorff)

This should ride the trains. The behavior is extremely old.

Flags: needinfo?(jorendorff)
Duplicate of this bug: 1468499
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: