Closed Bug 1799638 Opened 2 years ago Closed 2 years ago

Date: wrong Daylight Saving start time "hh:59:59.001"

Categories

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

Firefox 106
Desktop
All
defect

Tracking

()

VERIFIED FIXED
108 Branch
Tracking Status
firefox107 --- wontfix
firefox108 --- verified
firefox109 --- verified

People

(Reporter: god.doesnotnecessarilyplaydice, Assigned: anba)

References

(Blocks 1 open bug)

Details

Attachments

(2 files)

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

Steps to reproduce:

Past Daylight Saving Time (DST, Summer time) has wrong start time. DST should not start at "hh:59:59.001", but at "hh:00:00".

This issue has 2 ways to reproduce.

Reproduce by Firefox:

  1. Set your computer time zone to "Asia/Tokyo".
  2. Start F12 Developer Tools Javascript Console.
  3. Execute following Javascript cases. (The last 2 lines are wrong)
console.log((new Date("1948-05-01T23:59:59"))); // Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time)
console.log((new Date("1948-05-01T23:59:59")).getTimezoneOffset()); // -540
console.log((new Date("1948-05-01T23:59:59.000"))); // Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time)
console.log((new Date("1948-05-01T23:59:59.000")).getTimezoneOffset()); // -540
// following case is NG
console.log((new Date("1948-05-01T23:59:59.001"))); // Date Sun May 02 1948 00:59:59 GMT+1000 (Japan Daylight Time)
// following case is NG
console.log((new Date("1948-05-01T23:59:59.001")).getTimezoneOffset()); // -600
console.log((new Date("1948-05-02T00:00:00"))); // Date Sun May 02 1948 01:00:00 GMT+1000 (Japan Daylight Time)
console.log((new Date("1948-05-02T00:00:00")).getTimezoneOffset()); // -600
  1. Set your computer time zone to "America/New_York".
  2. Start F12 Developer Tools Javascript Console.
  3. Execute following Javascript cases.
console.log((new Date("1966-04-24T01:59:59"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
console.log((new Date("1966-04-24T01:59:59")).getTimezoneOffset()); // 300
console.log((new Date("1966-04-24T01:59:59.000"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
console.log((new Date("1966-04-24T01:59:59.000")).getTimezoneOffset()); // 300
// following case is NG
console.log((new Date("1966-04-24T01:59:59.001"))); // Date Sun Apr 24 1966 02:59:59 GMT-0400 (Eastern Daylight Time)
// following case is NG
console.log((new Date("1966-04-24T01:59:59.001")).getTimezoneOffset()); // 240
console.log((new Date("1966-04-24T02:00:00"))); // Date Sun Apr 24 1966 03:00:00 GMT-0400 (Eastern Daylight Time)
console.log((new Date("1966-04-24T02:00:00")).getTimezoneOffset()); // 240

Reproduce by SpiderMonkey:

  1. Execute following commands
$ TZ=Asia/Tokyo ./mach run
 0:00.33 /home/user/moz/mozilla-unified/obj-x86_64-pc-linux-gnu/dist/bin/js
js> console.log((new Date("1948-05-01T23:59:59")))
Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time)
js> console.log((new Date("1948-05-01T23:59:59")).getTimezoneOffset())
-540
js> console.log((new Date("1948-05-01T23:59:59.000")))
Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time)
js> console.log((new Date("1948-05-01T23:59:59.000")).getTimezoneOffset())
-540
js> console.log((new Date("1948-05-01T23:59:59.001")))
Sun May 02 1948 00:59:59 GMT+1000 (Japan Daylight Time)
js> console.log((new Date("1948-05-01T23:59:59.001")).getTimezoneOffset())
-600

$ TZ=America/New_York ./mach run
 0:00.32 /home/user/moz/mozilla-unified/obj-x86_64-pc-linux-gnu/dist/bin/js
js> console.log((new Date("1966-04-24T01:59:59")))
Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
js> console.log((new Date("1966-04-24T01:59:59")).getTimezoneOffset())
300
js> console.log((new Date("1966-04-24T01:59:59.000")))
Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
js> console.log((new Date("1966-04-24T01:59:59.000")).getTimezoneOffset())
300
js> console.log((new Date("1966-04-24T01:59:59.001")))
Sun Apr 24 1966 02:59:59 GMT-0400 (Eastern Daylight Time)
js> console.log((new Date("1966-04-24T01:59:59.001")).getTimezoneOffset())
240

$ hg log
changeset:   714960:cf9bf33343df
bookmark:    autoland
tag:         tip
user:        Mozilla Releng Treescript <release+treescript@mozilla.org>
date:        Tue Nov 08 06:58:10 2022 +0000
summary:     no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE

Actual results:

Actual results are described as above.

Expected results:

For "Asia/Tokyo":

console.log((new Date("1948-05-01T23:59:59"))); // Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time)
console.log((new Date("1948-05-01T23:59:59")).getTimezoneOffset()); // -540
console.log((new Date("1948-05-01T23:59:59.000"))); // Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time)
console.log((new Date("1948-05-01T23:59:59.000")).getTimezoneOffset()); // -540
// following case shows expected result
console.log((new Date("1948-05-01T23:59:59.001"))); // Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time)
// following case shows expected result
console.log((new Date("1948-05-01T23:59:59.001")).getTimezoneOffset()); // -540
console.log((new Date("1948-05-02T00:00:00"))); // Date Sun May 02 1948 01:00:00 GMT+1000 (Japan Daylight Time)
console.log((new Date("1948-05-02T00:00:00")).getTimezoneOffset()); // -600
  1. Set your computer time zone to "America/New_York".
  2. Start F12 Developer Tools Javascript Console.
  3. Execute following Javascript cases.
console.log((new Date("1966-04-24T01:59:59"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
console.log((new Date("1966-04-24T01:59:59")).getTimezoneOffset()); // 300
console.log((new Date("1966-04-24T01:59:59.000"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
console.log((new Date("1966-04-24T01:59:59.000")).getTimezoneOffset()); // 300
// following case is NG
console.log((new Date("1966-04-24T01:59:59.001"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
// following case is NG
console.log((new Date("1966-04-24T01:59:59.001")).getTimezoneOffset()); // 300
console.log((new Date("1966-04-24T02:00:00"))); // Date Sun Apr 24 1966 03:00:00 GMT-0400 (Eastern Daylight Time)
console.log((new Date("1966-04-24T02:00:00")).getTimezoneOffset()); // 240

Node.js returns correct getTimezoneOffset result.

Interestingly, Chrome returns correct getTimezoneOffset result, but returns incorrect DST notation (wrong "Japan Standard Time" or "Eastern Daylight Time").

FYI

https://github.com/eggert/tz/blob/2022f/asia#L2135
Rule Japan 1948 only - May Sat>=1 24:00 1:00 D

https://github.com/eggert/tz/blob/2022f/northamerica#L352
Rule NYC 1921 1966 - Apr lastSun 2:00 1:00 D

This issue seems to be related to IANA tz database "D" LETTER/S.

Assignee: nobody → andrebargull
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true

Add explicit casts to ensure the operations are performed using integer instead
of floating point math. Existing assertions ensure there won't be integer overflows.

Depends on D161591

Thanks for the report and the easy to reproduce example code!

Severity: -- → S3
Priority: -- → P1
Pushed by andre.bargull@gmail.com: https://hg.mozilla.org/integration/autoland/rev/dada805c432b Part 1: Round seconds towards the start-of-time in DateTimeInfo::toClampedSeconds(). r=dminor https://hg.mozilla.org/integration/autoland/rev/8e4d64161ddc Part 2: Add casts to avoid floating point math. r=dminor
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 108 Branch
Flags: qe-verify+

I've reproduced this issue in Firefox v107.0 and verified the fix in Beta v108.0b4 and Nightly v109.0a1 In Windows 10.

Test results:

  • Tokyo Time Zone:
    • Release v107.0:
      • console.log((new Date("1948-05-01T23:59:59"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59")).getTimezoneOffset()); -> -540 (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.000"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.000")).getTimezoneOffset()); -> -540 (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.001"))); -> Date Sun May 02 1948 00:59:59 GMT+1000 (Japan Daylight Time) (INCORRECT)
      • console.log((new Date("1948-05-01T23:59:59.001")).getTimezoneOffset()); -> -600 (INCORRECT)
      • console.log((new Date("1948-05-02T00:00:00"))); -> Date Sun May 02 1948 01:00:00 GMT+1000 (Japan Daylight Time) (CORRECT)
      • console.log((new Date("1948-05-02T00:00:00")).getTimezoneOffset()); -> -600 (CORRECT)
    • Beta v108.0b4:
      • console.log((new Date("1948-05-01T23:59:59"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59")).getTimezoneOffset()); -> -540 (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.000"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.000")).getTimezoneOffset()); -> -540 (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.001"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECTED!)
      • console.log((new Date("1948-05-01T23:59:59.001")).getTimezoneOffset()); -> -540 (CORRECTED!)
      • console.log((new Date("1948-05-02T00:00:00"))); -> Date Sun May 02 1948 01:00:00 GMT+1000 (Japan Daylight Time) (CORRECT)
      • console.log((new Date("1948-05-02T00:00:00")).getTimezoneOffset()); -> -600 (CORRECT)
    • Nightly v109.0a1:
      • console.log((new Date("1948-05-01T23:59:59"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59")).getTimezoneOffset()); -> -540 (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.000"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.000")).getTimezoneOffset()); -> -540 (CORRECT)
      • console.log((new Date("1948-05-01T23:59:59.001"))); -> Date Sat May 01 1948 23:59:59 GMT+0900 (Japan Standard Time) (CORRECTED!)
      • console.log((new Date("1948-05-01T23:59:59.001")).getTimezoneOffset()); -> -540 (CORRECTED!)
      • console.log((new Date("1948-05-02T00:00:00"))); -> Date Sun May 02 1948 01:00:00 GMT+1000 (Japan Daylight Time) (CORRECT)
      • console.log((new Date("1948-05-02T00:00:00")).getTimezoneOffset()); -> -600 (CORRECT)

I've reproduced this issue in Firefox v107.0 and verified the fix in Beta v108.0b4 and Nightly v109.0a1 In Ubuntu 22 for the other time zone exemplified.

Test results:

  • New York time zone:
    • Release v107.0:
      • console.log((new Date("1966-04-24T01:59:59"))); -> Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time) (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59")).getTimezoneOffset()); -> 300 (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59.000"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
      • console.log((new Date("1966-04-24T01:59:59.000")).getTimezoneOffset()); -> 300 (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59.001"))); -> Date Sun Apr 24 1966 02:59:59 GMT-0400 (Eastern Daylight Time) (INCORRECT)
      • console.log((new Date("1966-04-24T01:59:59.001")).getTimezoneOffset()); -> 240 (INCORRECT)
      • console.log((new Date("1966-04-24T02:00:00"))); -> Date Sun Apr 24 1966 03:00:00 GMT-0400 (Eastern Daylight Time) (CORRECT)
      • console.log((new Date("1966-04-24T02:00:00")).getTimezoneOffset()); -> 240 (CORRECT)
    • Beta v108.0b4:
      • console.log((new Date("1966-04-24T01:59:59"))); -> Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time) (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59")).getTimezoneOffset()); -> 300 (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59.000"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
      • console.log((new Date("1966-04-24T01:59:59.000")).getTimezoneOffset()); -> 300 (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59.001"))); -> Date Sun Apr 24 1966 01:59:59 GMT-0400 (Eastern Daylight Time) (CORRECTED!)
      • console.log((new Date("1966-04-24T01:59:59.001")).getTimezoneOffset()); -> 300 (CORRECTED!)
      • console.log((new Date("1966-04-24T02:00:00"))); -> Date Sun Apr 24 1966 03:00:00 GMT-0400 (Eastern Daylight Time) (CORRECT)
      • console.log((new Date("1966-04-24T02:00:00")).getTimezoneOffset()); -> 240 (CORRECT)
    • Nightly v109.0a1:
      • console.log((new Date("1966-04-24T01:59:59"))); -> Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time) (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59")).getTimezoneOffset()); -> 300 (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59.000"))); // Date Sun Apr 24 1966 01:59:59 GMT-0500 (Eastern Standard Time)
      • console.log((new Date("1966-04-24T01:59:59.000")).getTimezoneOffset()); -> 300 (CORRECT)
      • console.log((new Date("1966-04-24T01:59:59.001"))); -> Date Sun Apr 24 1966 01:59:59 GMT-0400 (Eastern Daylight Time) (CORRECTED!)
      • console.log((new Date("1966-04-24T01:59:59.001")).getTimezoneOffset()); -> 300 (CORRECTED!)
      • console.log((new Date("1966-04-24T02:00:00"))); -> Date Sun Apr 24 1966 03:00:00 GMT-0400 (Eastern Daylight Time) (CORRECT)
      • console.log((new Date("1966-04-24T02:00:00")).getTimezoneOffset()); -> 240 (CORRECT)

Based on the last comments with detailed test results, I confirm this fix in Beta v108.0a4 and Nightly v109.0a1.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
OS: Unspecified → All
Hardware: Unspecified → Desktop
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: