-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default hour-cycle computation can resolve to non-preferred hour format #402
Comments
cc @zbraniecki |
This issue seems somewhat important--it is a sort of user-observable "bug". Should we put it on the ES2021 milestone? |
I consider it a bug. The assumption in the spec is that h11 maps to h23 and h12 maps to h24, as a logical preference is wrong. We can see from various bugs in date formatting packages that are following the spec that this is surprising. hourCycle options map to keys in https://unicode.org/reports/tr35/tr35-dates.html#dfst-hour
either;
all these algorithms should evaluate to the same thing.
|
So, if I'm correct, SpiderMonkey enforces |
SpiderMonkey uses the following hour symbols in the skeleton:
(Input skeletons don't differentiate between With that approach we don't strictly enforce js> print(new Intl.DateTimeFormat("en", {hour:"numeric", hour12:true, timeZone:"UTC"}).format(new Date("2020-01-01T12:00Z")))
12 PM
js> print(new Intl.DateTimeFormat("ja", {hour:"numeric", hour12:true, timeZone:"UTC"}).format(new Date("2020-01-01T12:00Z")))
午後0時 |
I was bitten by this V8 change early this week https://bugs.chromium.org/p/chromium/issues/detail?id=1045791#c7. |
What I'm missing with the hourCycle option is a 0-24. |
I know that at least with german speaking locales having midnight as endtime with No idea about other locales. |
@ray007 In this case, it's hard for me to see what sort of setting for Intl.DateTimeFormat would permit both 0:00 and 24:00 to be generated with the same formatter... |
No need. |
@ray007 While there are cases of 24:00 (or later) being used as the end times of a duration this issue should concern it's self with resolving the existing discrepancy between new v8, the spec, and spidermonkey etc. mapping 24hour to hourCycle A new proposal for a new hourCycle (or other) for handling this might be successful, though ecma402 tends to consume upstream standards and I note in particular changes in the latest version of ISO-8601
|
@anba I think the correct way to fix this is to modify the standard to expect the spidermonkey (and old v8) behaviour. To me this matches most expectations and more closely matches cldr data. A more sophisticated algorithm would need to account for whether the AM/PM section is shown or not. @FrankYFTang The recent changes to Chromium - are they simply to match the spec? Do we have any additional information about why the spec was written that way. |
I start to work on v8 after ECMA402 added the hourCycle algorithm and at that time v8 break a lot of test262 tests. The hourCycle algorithm in the ECMA402 spec is very complex and I am not sure WHY it was written in that way and I spent some effort to engineering it to match what the current spec (and therefore test262) stated in order to make v8 pass those tests. By default is hard to make ICU to behave like what the current ECMA402 states and maybe exactly why anba stated. I have not spend efforts to figure out the spec "make sense" or NOT and only ASSUME those before my involvement to ECMA402 already figure out it correctly. Now after I look at what Anba wrote I finally realize maybe the fault is on the spec but not the v8 code before my "fixing". I am totally fine if someone can figure out what the HourCycle algorithm should be and I will change v8 code to meet that. (It take me a long time to make the v8 switch to h24 on "en" but I am totally fine to change it.) |
@sffc I think this one is important to discuss in our next meeting. |
We should comment / review on #436 to address this issue. I need to read through that PR. (not yet) |
FYI, we aligned JavaScriptCore behavior to SpiderMonkey's one described in #402 (comment) :) |
…s used https://bugs.webkit.org/show_bug.cgi?id=216521 Reviewed by Ross Kirsling. JSTests: JSTests/stress/intl-date-time-format-date-time-style-hour-cycle.js result is now matching against V8 and SpiderMonkey, and this new behavior is more reasonable. * stress/intl-date-time-format-date-time-style-hour-cycle.js: (shouldBe.o.format): (shouldBe): * stress/intl-datetimeformat-hour-cycle.js: Added. (shouldBe): (throw.new.Error): * test262/expectations.yaml: Source/JavaScriptCore: When specifying timeStyle in Intl.DateTimeFormat, we need to check that the generated format also follows to the hourCycle / hour12 options specified in the constructor. Because dayPeriod can be included automatically, just replacing symbols after generating a pattern can dump strange result. For example, the generated one is something like "02:12:47 PM Coordinated Universal Time". And we adjust the pattern to make it "14:12:47 PM Coordinated Universal Time" when hourCycle H23 / H24 is specified. But this looks strange since dayPeriod "PM" should not exist when using H23 / H24. In this patch, we revise our hour-cycle handling in Intl.DateTimeFormat. We align our behavior to SpiderMonkey's one[1] rather than the spec's one: when hour12 is specified, we will just use 'H' or 'h' skeleton and do not enforce hour-cycle after generating pattern in hour12 case. If hour12 is not specified, then we use 'h' or 'H' skeleton symbols based on hour-cycle, and later we modify the pattern based on hour-cycle. If both are not offered, we use 'j' which allows ICU to pick preferable one. This is slightly different behavior to the spec (hcDefault etc.) but the spec's behavior can cause a bit surprising result[2,3], and SpiderMonkey like behavior will be integrated into the spec eventually[4]. [1]: tc39/ecma402#402 (comment) [2]: tc39/ecma402#402 [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=1045791 [4]: tc39/ecma402#436 * runtime/IntlDateTimeFormat.cpp: (JSC::IntlDateTimeFormat::setFormatsFromPattern): (JSC::IntlDateTimeFormat::parseHourCycle): (JSC::IntlDateTimeFormat::hourCycleFromPattern): (JSC::IntlDateTimeFormat::replaceHourCycleInSkeleton): (JSC::IntlDateTimeFormat::replaceHourCycleInPattern): (JSC::IntlDateTimeFormat::initializeDateTimeFormat): (JSC::IntlDateTimeFormat::hourCycleString): (JSC::IntlDateTimeFormat::resolvedOptions const): (JSC::IntlDateTimeFormat::createDateIntervalFormatIfNecessary): * runtime/IntlDateTimeFormat.h: Canonical link: https://commits.webkit.org/229387@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@267108 268f45cc-cd09-0410-ab3c-d52691b4dbfc
I would really like to see this being resolved. |
This is also broken in other cases than just h24: new Intl.DateTimeFormat("fr-CA", {hour: "numeric", hour12: true}).format(new Date(2020, 2, 3, 0)) Chrome returns |
@sffc @FrankYFTang is there a plan to fix this bug in the spec? FWIW, it seems like anyone who's building a date/time-related library seems to run into this bug sooner or later. In Temporal we fixed it in tc39/proposal-temporal#599 (my first Temporal PR, BTW). Looks like @devongovett just ran into it too with his cool internationalized date/time picker library. |
While hour12 is either true or false, let hourCycle to be either 'h12' or 'h23' but not 'h11' nor 'h24'. The current logic is not reasonable. We see no region in the CLDR use h11 nor h24 hour cycle as default. While we set a hour12: true on a 24 hour system region (which use 0:00 - 23:59), we should set to h12 instead of h11 Do not perform the starnge logic of setting default hourCycle based on both hour12 and the defaultHourCycle while hour12 is true or false. Instead, only depends on hour12 to set it to h12 or h23. Address #402
While hour12 is either true or false, let hourCycle to be either 'h12' or 'h23' but not 'h11' nor 'h24'. The current logic is not reasonable. We see no region in the CLDR use h11 nor h24 hour cycle as default. While we set a hour12: true on a 24 hour system region (which use 0:00 - 23:59), we should set to h12 instead of h11 Do not perform the starnge logic of setting default hourCycle based on both hour12 and the defaultHourCycle while hour12 is true or false. Instead, only depends on hour12 to set it to h12 or h23. Address tc39#402
@here is there a desire to resolve this because I think there's some implicit assumptions baked into the specification that have not been (or at least, from the documentary evidence left behind, I can't see that they have been) appropriately tested for each locale expectation. I imagine a critical change would, if the convention of EDIT: of course #758 |
While hour12 is either true or false, let hourCycle to be either 'h12' or 'h23' but not 'h11' nor 'h24'. The current logic is not reasonable. We see no region in the CLDR use h11 nor h24 hour cycle as default. While we set a hour12: true on a 24 hour system region (which use 0:00 - 23:59), we should set to h12 instead of h11 Do not perform the starnge logic of setting default hourCycle based on both hour12 and the defaultHourCycle while hour12 is true or false. Instead, only depends on hour12 to set it to h12 or h23. Address #402 Co-authored-by: Shane F. Carr <[email protected]> Co-authored-by: Ujjwal Sharma <[email protected]> Co-authored-by: André Bargull <[email protected]>
While hour12 is either true or false, let hourCycle to be either 'h12' or 'h23' but not 'h11' nor 'h24'. The current logic is not reasonable. We see no region in the CLDR use h11 nor h24 hour cycle as default. While we set a hour12: true on a 24 hour system region (which use 0:00 - 23:59), we should set to h12 instead of h11 Do not perform the starnge logic of setting default hourCycle based on both hour12 and the defaultHourCycle while hour12 is true or false. Instead, only depends on hour12 to set it to h12 or h23. Address tc39#402 Co-authored-by: Shane F. Carr <[email protected]> Co-authored-by: Ujjwal Sharma <[email protected]> Co-authored-by: André Bargull <[email protected]>
Fixed in #758. |
https://github.com/tc39/test262/blob/master/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js is currently failing in SpiderMonkey, revealing a potential spec issue.
Reduced test case:
Returns in SpiderMonkey:
But in V8 (and per current spec):
InitializeDateTimeFormat, step 30.d for
hcDefault=h12
, computeshc=hc12
forhour12=true
resp.hc=hc24
forhour12=false
.But when we're consulting CLDR's supplementalData.xml for "US" [1], the preferred hour formats are either "h" or "H", which means either "hc12" or "hc23". So "hc24" is likely an unexpected result for US, because "k" isn't listed in the preferred hour formats for that region. (See [2] for "h", "H", and "k".)
[1] Adding likely subtags to the "en" locale results in "en-Latn-US".
[2] https://unicode.org/reports/tr35/tr35-dates.html#dfst-hour
The text was updated successfully, but these errors were encountered: