Thursday, April 29, 2021

Firefox toLocaleString displays wrong time on OpenBSD

I'm confused about Firefox's handling of Date objects on OpenBSD.

Why: Some Firefox browser extensions that display dates using
Date.toLocaleString or Date.toLocaleDateString can cause an incorrect
date to be displayed. For example, using a credit card expiration
displayed as "01/23" when it really expires in February 2023 will make
payments fail.

Synopsis: Calling toLocaleString without parameters on a date object
seems to yield the wrong time.

Description: Calling toLocaleString without parameters yields a
time that is one hour off for CST and two hours off for CDT. This
seems to happen only on Firefox with OpenBSD -- not on Chromium on
the same machine, nor on Firefox on other operating systems that
I've tried.

This problem will show up if you go to Web Developer -> Web Developer
Tools and try any dates in the console.

However, if you are in a Preferences tab and try it in the web
developer console, the error will NOT show up.

The error will also NOT show up if you use Date.toLocaleString
within a regular web page.

It only appears for me from the browser extension that uses
Date.toLocaleString, and in the developer console from a tab that
is not "Preferences."

I think this is a Firefox bug and have reported it to Mozilla.
I've reproduced the error on many OpenBSD machines for the last
several months all running -current, with various version of Firefox,
including 88.0.

(My first attempt to get the source from ports failed because of
an anemic machine, but I will try again with more memory.)

Sadly, I've been banging my head against this problem for a long
time. I initially and stupidly submitted to the wrong forum, and
compounded the problem with an ill-formatted date, although I had
tried valid dates as well. My example was unfortunate because, as
far as I can tell, any date will generate this problem.

My BIOS time is set to UTC and /etc/localtime points to US/Central.
I've also tried changing the BIOS time to my local time and setting
kern.utc_offset, but nothing changed.

I also tried the Firefox option to use the operating system's setting
to format dates just to see if that might affect anything, not
expecting it to change anything. Indeed, nothing changed.

As far as I can tell from reading developer.mozilla.org about
Date and Date.prototype.toLocalString and international formats, etc.,
calling toLocaleString without parameters might use an
unpredictable format, but the time displayed should be local time.

Some forum posts such as

https://stackoverflow.com/questions/33083936/
convert-date-to-local-time-zone-with-tolocalestring-method-firefox


say this is a bug in Firefox.

How-To-Repeat:
From Web Developer -> Web Developer Tools in Firefox:
(with input and output marked, and comments starting with #)

# I've created the dates with new Date but
# new Date(Date.UTC(.....)) doesn't change the results
# of the call to toLocaleString

# create date in Central Standard Time. so far so good
INPUT: event1 = new Date(2021, 0, 1, 12, 0, 0)
OUTPUT Date Fri Jan 01 2021 12:00:00 GMT-0600 (CST)

# output below of toLocaleString() is one hour before local
# time. Happens to match Canada/Mountain

INPUT: event1.toLocaleString()
OUTPUT: "1/1/2021, 11:00:00 AM"

INPUT: event1.toLocaleString('en-US', {timeZone: "Canada/Mountain"})
OUTPUT: "1/1/2021, 11:00:00 AM"

INPUT: event1.toLocaleString('en-US', {timeZone: "US/Central"})
OUTPUT: "1/1/2021, 12:00:00 PM"

# create date in Central Daylight Time. so far so good
INPUT: event2 = new Date(2021, 3, 29, 12, 0, 0);
OUTPUT: Date Thu Apr 29 2021 12:00:00 GMT-0500 (CDT)

# output below of toLocaleString()is two hours before local
# time. Happens to match Canada/Pacific

INPUT: event2.toLocaleString()
OUTPUT: "4/29/2021, 10:00:00 AM"

INPUT: event2.toLocaleString('en-US', {timeZone: "Canada/Pacific"})
OUTPUT: "4/29/2021, 10:00:00 AM"

INPUT: event2.toLocaleString('en-US', {timeZone: "US/Central"})
OUTPUT: "4/29/2021, 12:00:00 PM"

Fix: A workaround in the console: specify parameters to toLocaleString.
To workaround the display problem in the browser extension, set
privacy.resistfingerprinting to true. I think everything looks like
UTC, so any conversion problems seem to go away.

No comments:

Post a Comment