Skip to content

Conversation

@sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Mar 22, 2024

Followup to #21585

@sbc100 sbc100 requested review from dschuff and kripken March 22, 2024 16:13
@sbc100 sbc100 changed the title For en-US locale when extracting timezone info Fix en-US locale when extracting timezone info Mar 22, 2024
@jrobichaux
Copy link

Could you do something like: https://stackoverflow.com/a/78194184 ?

var timeParts = new Intl.DateTimeFormat(undefined, {timeZoneName: 'short'}).formatToParts(date);
var extractZone = timeParts.find(item => item.type == 'timeZoneName').value;

I don't know if timeZoneName is guaranteed to exist, based on the Mozilla docs on Intl.DateTimeFormat so you might want some error checks around that.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 22, 2024

Could you do something like: https://stackoverflow.com/a/78194184 ?

var timeParts = new Intl.DateTimeFormat(undefined, {timeZoneName: 'short'}).formatToParts(date);
var extractZone = timeParts.find(item => item.type == 'timeZoneName').value;

I don't know if timeZoneName is guaranteed to exist, based on the Mozilla docs on Intl.DateTimeFormat so you might want some error checks around that.

The hours12 solution looks like it should less code and just as reliable.

My reading of the MDN page is that timeZoneName should be available everywhere we support running. I added some assertions in case we do run into any places where its not. I think we should avoid adding fallbacks/checking in release builds until we know we need it.

@sbc100 sbc100 changed the title Fix en-US locale when extracting timezone info Use short timezone name when extracting timezone info in JS Mar 22, 2024
@sbc100 sbc100 changed the title Use short timezone name when extracting timezone info in JS Fix timezone extraction to work in all locales Mar 22, 2024
@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 22, 2024

Could you do something like: https://stackoverflow.com/a/78194184 ?

var timeParts = new Intl.DateTimeFormat(undefined, {timeZoneName: 'short'}).formatToParts(date);
var extractZone = timeParts.find(item => item.type == 'timeZoneName').value;

I don't know if timeZoneName is guaranteed to exist, based on the Mozilla docs on Intl.DateTimeFormat so you might want some error checks around that.

The hours12 solution looks like it should less code and just as reliable.

My reading of the MDN page is that timeZoneName should be available everywhere we support running. I added some assertions in case we do run into any places where its not. I think we should avoid adding fallbacks/checking in release builds until we know we need it.

I tested this code going back to node v14.1.0 and also in the d8 shell and it seems to work fine.

@sbc100 sbc100 enabled auto-merge (squash) March 22, 2024 20:12
@sbc100 sbc100 requested review from dschuff and kripken March 22, 2024 20:12
@jrobichaux
Copy link

One more thing and I promise I'll leave you alone. :)

You might want to have a test with a time in a timezone with a 15 or 30 minute offset. For example:

new Date().toLocaleTimeString(undefined, {hour12:false, timeZoneName:'short', timeZone:'Asia/Kathmandu'}).split(' ')[1]

returns GMT+5:45 for me, which would break your 6 character TZNAME_MAX.

I am SO sorry this blew up into so much work. Time zones and locales are HARD.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 22, 2024

One more thing and I promise I'll leave you alone. :)

You might want to have a test with a time in a timezone with a 15 or 30 minute offset. For example:

new Date().toLocaleTimeString(undefined, {hour12:false, timeZoneName:'short', timeZone:'Asia/Kathmandu'}).split(' ')[1]

returns GMT+5:45 for me, which would break your 6 character TZNAME_MAX.

Do you know how POSIX/glibc handles this case? Should we just silently truncate to 6 chars since this is such an outlier case?

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 22, 2024

One more thing and I promise I'll leave you alone. :)
You might want to have a test with a time in a timezone with a 15 or 30 minute offset. For example:
new Date().toLocaleTimeString(undefined, {hour12:false, timeZoneName:'short', timeZone:'Asia/Kathmandu'}).split(' ')[1]
returns GMT+5:45 for me, which would break your 6 character TZNAME_MAX.

Do you know how POSIX/glibc handles this case? Should we just silently truncate to 6 chars since this is such an outlier case?

Answering my own question it looks like glibc prints +0545 in this case rather than a 3 letter timezone name.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 22, 2024

Updated TZNAME_MAX to be 16 in order to handle 'Asia/Kathmandu'. Also added test for this particular timezone.

@sbc100 sbc100 force-pushed the fix_timezone branch 2 times, most recently from 416cf52 to ab2068f Compare March 22, 2024 21:10
@sbc100 sbc100 merged commit 829b626 into emscripten-core:main Mar 25, 2024
@sbc100 sbc100 deleted the fix_timezone branch March 25, 2024 22:40
@dschuff
Copy link
Member

dschuff commented Mar 26, 2024

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 26, 2024

Oh way, I disabled it under macOS on github CI, but maybe I just need to disable it completely on macOS.

@dschuff can you confirm if fails for you locally on your mac? Do you think is reasonable to simpley not support the locale testing on mac for this reason?

@dschuff
Copy link
Member

dschuff commented Mar 26, 2024

Yes, this fails locally for me with

Fatal Python error: config_get_locale_encoding: failed to get the locale encoding: nl_langinfo(CODESET) failed
Python runtime state: preinitialized

Which is the same failure on the Chromium bots, and I guess is the same failure you saw on Circle, right (i.e. python just doesn't work when you ask it for a locale that's not on the system?)

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 26, 2024

Do you know how locales work on macOS? Is this s limitation of the OS, or of the python executable that we ship?

@dschuff
Copy link
Member

dschuff commented Mar 26, 2024

No idea how locales work really. The python executable I'm using locally is not the one we ship though.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 26, 2024

OK I think we will just have to disable that test on mac in all cases then.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 26, 2024

#21624

sbc100 pushed a commit that referenced this pull request Jul 18, 2024
With certain language I've noticed that the timezone extraction
algorithm doesn't work.  or example consider the following:


Test file:
```JavaScript
const date = new Date();
console.log(date.toLocaleTimeString(undefined, {hour12: false, timeZoneName: 'short'}))
```

Run test file with specific local such as `th-TH` or `ar-AE`
```bash
LC_ALL="th-TH" TZ="Asia/Bangkok" node test.js
# prints "15 นาฬิกา 53 นาที 54 วินาที GMT+7"
```
And so the current logic for extracting would fail and return "นาฬิกา" (second item when splitting by space)

In this PR, a new approach is proposed for extracting the timezone offset and tests are updated with new test-case


See #21596
verhovsky pushed a commit to verhovsky/emscripten that referenced this pull request Jul 30, 2024
…ten-core#22250)

With certain language I've noticed that the timezone extraction
algorithm doesn't work.  or example consider the following:


Test file:
```JavaScript
const date = new Date();
console.log(date.toLocaleTimeString(undefined, {hour12: false, timeZoneName: 'short'}))
```

Run test file with specific local such as `th-TH` or `ar-AE`
```bash
LC_ALL="th-TH" TZ="Asia/Bangkok" node test.js
# prints "15 นาฬิกา 53 นาที 54 วินาที GMT+7"
```
And so the current logic for extracting would fail and return "นาฬิกา" (second item when splitting by space)

In this PR, a new approach is proposed for extracting the timezone offset and tests are updated with new test-case


See emscripten-core#21596
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants