RangeError on Chrome for Android only
khawarizmus opened this issue · 10 comments
The following snippet of code works well on all major browsers (desktop) and it works on Firefox for android as well as safari for IOS
const HijriT = Temporal.Now.zonedDateTime("islamic-umalqura", timeZone);
console.log(HijriT.day);
However on Chrome for Android it throws the following error:
RangeError: era must be ah, not bc
My chrome version is 142.0.6367.179
Tested no Android 14.
If it helps the error is coming from here
This looks like a bug in Intl.DateTimeFormat
on this version of Chrome for Andriod. To confirm, run this code on the android device:
new Intl.DateTimeFormat(`en-US-u-ca-islamic-umalqura`, { era: 'short' })
.formatToParts(new Date(2024, 04, 27))
.find(part => part.type === 'era')
.value
If it returns "AH" (as it does on Chrome for Mac 125.0.6422.77) then it's working properly. If it returns "BC" then there's a problem with the calendar data available on that version of Chrome.
It might be that this particular Android version was not compiled with non-Gregorian calendar data. You can check this by simply running this:
new Intl.DateTimeFormat(`en-US-u-ca-islamic-umalqura`, { era: 'short' })
.formatToParts(new Date(2024, 04, 27))
Do the results look like Gergorian dates or Islamic calendar dates? This will be useful into to put in your bug report.
@sffc if this is indeed an Android-specific Chrome bug with Intl.DateTimeFormat
, where should a bug report be filed?
Thank you for the swift reply. It seems that indeed the era is not being resolved properly. as:
console.log(
"Era",
new Intl.DateTimeFormat("en-US-u-ca-islamic-umalqura", { era: "short" })
.formatToParts(new Date(2024, 4, 27))
.find((part) => part.type === "era")?.value
);
Outputs "Era BC"
However the rest of the data seems to be working fine only the era seems problematic as:
console.log(
"date",
new Intl.DateTimeFormat(`en-US-u-ca-islamic-umalqura`, {
era: "short",
}).formatToParts(new Date(2024, 4, 27))
);
Prints
[
{
"type": "month",
"value": "11"
},
{
"type": "literal",
"value": "/"
},
{
"type": "day",
"value": "19"
},
{
"type": "literal",
"value": "/"
},
{
"type": "year",
"value": "1445"
},
{
"type": "literal",
"value": " "
},
{
"type": "era",
"value": "BC"
}
]
I would be happy to file a bug wherever it should be if I am directed.
Also worth noting that on the same Android phone Firefox for Android works fine. so the non-Gregorian data is being compiled properly and it seems that it's a bug specifically on Chrome for android.
Looks like this bug was already reported here: https://issues.chromium.org/issues/40856332
You'll want to watch that issue for status.
If you want to try making a PR to work around this issue in Temporal polyfills, we'd be happy to review it. Please file the PR in the proposal-temporal repo and the commit will eventually percolate down here to this repo.
The fix you'll probably want to try is to override the reviseIntlEra
method in helperIslamic
. Take a look at the implementation of this method in helperGregory
for inspiration.
Thank you for the guidance @justingrant I appreciate it. I will raise a PR today or tomorrow.
@justingrant FYI. I have raised a PR for this here as advised.
@justingrant will the patch be published to npm? if yes, then I would appreciate it if I could know when
it will eventually, the production polyfill in the other repo needs to get caught up with upstream and that may take a while.
There's another polyfill from @arshaw that's probably closer to upstream at this point. FYI Adam, you may want to pick up this fix too.
@khawarizmus, I just released v0.2.5 of temporal-polyfill
(aka the "fullcalendar" polyfill) and it contains an attempt at a bugfix for your issue. Would you mind testing?
Hey @arshaw. Thank you for the fix and apologies for taking some time to reply. I have already managed to get thinsg working by using pnpm-patch-i. I have a lot of code (including published libraries) that rely on the @js-temporal/polyfill
hence switching to your polyfill might not be straight forward for me.
However I went ahead and tested your polyfill (using v0.2.5).
The following code
const HDate = FullTemporal.Now.zonedDateTime("islamic-umalqura", timeZone);
console.log(HDate.day);
console.log(
new FullIntl.DateTimeFormat(locale.value, {
era: "short",
calendar: Calendars.UMM_AL_QURA,
}).format(HDate.toInstant())
);
console.log(
new FullIntl.DateTimeFormat(locale.value, {
dateStyle: "full",
calendar: Calendars.UMM_AL_QURA,
}).format(HDate.toInstant())
);
outputs:
26
11/26/1445 BC, 10:18:22 AM
Monday, November 26, 1445 BC
The numbers are correct. the line console.log(HDate.day)
doesn't throw an error. However the era is still wrong BC
instead of AH
. Note that the Months names i.e (November instead of Dull-Qidah) are wrong for both your polyfill and the patched version of @js-temporal/polyfill
and it's something that should be fixed at Chrome level i suppose, unless you guys know of a way to fix it. currently i am just hard coding the months in an array and reaching to the right index when i want to display them.
Thanks for checking @khawarizmus. Glad my fix works for fixing the numbers, but sad the fix doesn't apply to Intl.DateTimeFormat. More extensive monkeypatching/polyfilling would need to happen on Intl.DateTimeFormat to get this to work as you guessed.