Open Bug 1868317 Opened 2 years ago Updated 2 years ago

Date.setHours produces unexpected results across timezones

Categories

(Core :: Privacy: Anti-Tracking, defect, P3)

Firefox 120
defect

Tracking

()

People

(Reporter: connor.holloway, Unassigned)

References

(Blocks 1 open bug)

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:120.0) Gecko/20100101 Firefox/120.0

Steps to reproduce:

Modified example from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours#try_it

event = new Date('2023-07-01T00:00:00.000Z');
console.log("Original", event)
event.setHours(20);
console.log("20H", event);
event.setHours(0, 0, 0, 0);
console.log("0H", event);

Actual results:

Output

Original Date Sat Jul 01 2023 01:00:00 GMT+0100 (British Summer Time)
20H Date Sat Jul 01 2023 21:00:00 GMT+0100 (British Summer Time)
0H Date Sat Jul 01 2023 01:00:00 GMT+0100 (British Summer Time)

Expected results:

Date.setHours sets the hours according to the local time of the date.
I am not entirely sure what the actual results should be but this is an inconsistency between Chrome and Firefox.

Output

Original Date Sat Jul 01 2023 01:00:00 GMT+0100 (British Summer Time)
20H Date Sat Jul 01 2023 20:00:00 GMT+0100 (British Summer Time)
0H Date Sat Jul 01 2023 00:00:00 GMT+0100 (British Summer Time)

Moving this over to a potential component: JavaScript Engine, as I am not sure where this would fit best. If this is not the right, please change to a more suitable one.
Thanks!

Component: Untriaged → JavaScript Engine
Product: Firefox → Core

Vinny: Not sure if there's something here, but given your recent Date adventures thought I'd let you take a peek

Severity: -- → S3
Flags: needinfo?(vinny.diehl)
Priority: -- → P3

Moving this to Standard Library with the rest of them. However, I'm unable to reproduce this:

> eshost -tx 'const d = new Date("2023-07-01T00:00:00.000Z"); d.setHours(20); print(d)'
Engine Result
JavaScriptCore Fri Jun 30 2023 20:00:00 GMT-0700 (Mountain Standard Time)
SpiderMonkey Fri Jun 30 2023 20:00:00 GMT-0700 (Mountain Standard Time)
V8 Fri Jun 30 2023 20:00:00 GMT-0700 (Mountain Standard Time)

I have tried setting my time zone GMT+0100 as used in the bug report, but still cannot reproduce:

> eshost -tx 'const d = new Date("2023-07-01T00:00:00.000Z"); d.setHours(20); print(d)'
Engine Result
JavaScriptCore Sat Jul 01 2023 20:00:00 GMT+0100 (British Summer Time)
SpiderMonkey Sat Jul 01 2023 20:00:00 GMT+0100 (British Summer Time)
V8 Sat Jul 01 2023 20:00:00 GMT+0100 (British Summer Time)

I have also tried in-browser, both FF120 and FF122, with the code copied and pasted into the console from comment 0 and it seems to work as expected. Is there something I'm missing, Connor?

Component: JavaScript Engine → JavaScript: Standard Library
Flags: needinfo?(vinny.diehl) → needinfo?(connor.holloway)

The component has been changed since the backlog priority was decided, so we're resetting it.
For more information, please visit BugBot documentation.

Priority: P3 → --
Priority: -- → P3

I can still confirm the bug occurs on a system with MacOS 13.6.1 (22G313).
However it doesn't occur if I use the MDN playground and it also doesn't occur on another system running Debian Bullseye.

Flags: needinfo?(connor.holloway)

I can reproduce the issue using a new profile by adding the following to prefs.js

user_pref("privacy.resistFingerprinting", true);

Prior to adding that line everything behaves as expected. After adding that line the incorrect behaviour appears.
Note that this has to be run with a website loaded, the problem doesn't occur on the new tab page.

Component: JavaScript: Standard Library → Privacy: Anti-Tracking

Thanks Connor, I got this reproduced on Linux by setting that pref.

Any pointers on how I should go about unit testing this, guys? Can jstests take browser prefs into account, or will I have to spawn a browser, load a page and do something creative?

Flags: needinfo?(mgaudet)
Flags: needinfo?(arai.unmht)

Given the logic around RFP is implemented on the browser side, JS shell doesn't fit the purpose.

https://searchfox.org/mozilla-central/rev/82ce14a9dc278584b868b2b9c252ba0871a7782b/toolkit/components/resistfingerprinting/nsRFPService.cpp#216-217

JS::SetReduceMicrosecondTimePrecisionCallback(
    nsRFPService::ReduceTimePrecisionAsUSecsWrapper);

You can use xpcshell test, which is also shell-based test harness (no GUI), but it's capable of accessing the most of browser internal.
There's already a testcase that tests the Date behavior with the pref. You can add similar one.
in contrast to jstests or jit-test, xpcshell requires the test file to be registered in the manifest file

https://firefox-source-docs.mozilla.org/testing/xpcshell/index.html

Flags: needinfo?(arai.unmht)

Thanks! I'll look into this soon as I get the chance, I'm sure it's something interesting.

Flags: needinfo?(mgaudet)
Status: UNCONFIRMED → NEW
Ever confirmed: true
You need to log in before you can comment on or make changes to this bug.