-
Notifications
You must be signed in to change notification settings - Fork 104
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
Normative: Add dayPeriod option #346
Conversation
Format Day Periodvar dtf = new Intl.DateTimeFormat("en", {hour: "numeric", dayPeriod: "short"});
dtf.format(new Date("2019-05-20T07:00:00")); // "7 in the morning"
dtf.formatToParts(new Date("2019-05-20T07:00:00"));
// [{type: "hour", value: "7"},
// {type: "literal", value: " "},
// {type: "dayPeriod", value: "in the morning"}]
dtf.format(new Date("2019-05-20T11:59:00")); // "11 in the morning"
dtf.format(new Date("2019-05-20T12:00:00")); // "12 noon"
dtf.format(new Date("2019-05-20T13:00:00")); // "1 in the afternoon"
dtf.format(new Date("2019-05-20T18:00:00")); // "6 in the evening"
dtf.format(new Date("2019-05-20T22:00:00")); // "10 at night"
dtf = new Intl.DateTimeFormat("zh-Hant", {hour: "numeric", dayPeriod: "short"});
dtf.format(new Date("2019-05-20T07:00:00")); // "清晨7時"
dtf.formatToParts(new Date("2019-05-20T07:00:00"));
// [{type: "dayPeriod", value: "清晨"},
// {type: "hour", value: "7"},
// {type: "literal", value: "時"}]
dtf.format(new Date("2019-05-20T11:59:00")); // "上午11時"
dtf.format(new Date("2019-05-20T12:00:00")); // "中午12時"
dtf.format(new Date("2019-05-20T13:00:00")); // "下午1時"
dtf.format(new Date("2019-05-20T18:00:00")); // "下午6時"
dtf.format(new Date("2019-05-20T22:00:00")); // "晚上10時" |
v8 prototype in https://chromium-review.googlesource.com/c/v8/v8/+/1621445 |
To address #343 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I wonder if we could fit a note to the specs telling what a dayPeriod means as the examples in this PR are super useful.
The calculation is quite complex since for each locale, AFTER decide the locale hour by considering TimeZone and inDST,
In ICU, this information came from CLDR, 1) and 2) are covered in For example:
and then later
and for 3) of en: in https://cs.chromium.org/chromium/src/third_party/icu/source/data/locales/en.txt
and for 3) of zh-Hant: in https://cs.chromium.org/chromium/src/third_party/icu/source/data/locales/zh_Hant.txt
|
Is it expected that you can use any combination of dayPeriod with hourCycle, or does dayPeriod imply a locale-dependent "informal" hourCycle? |
I'm also wondering how "dayPeriod" should relate to the "ampm" field in formatToParts. |
The ampm field is not an option in the options to be controlled by the caller to output or not, but rather a field that decided by the pattern of the locale to output depending on the hourcycle. Therefore, it should depending the pattern in the locale data to decide, not in the algorithm of ECMA402 to decide. |
yes, it should be use any combination of dayPeriod with hourCycle. |
We have discussed this PR in Jun 5 2019 TC39 and decided this is small enough and align with pre-existing API already and therefore does not need to form a staged proposal but do require consensus with in ECMA402 committee + tests in test262 + 1 js engine implementation and no concern from other js implementation to land into ECMC402 as stage 4. |
Has any thought been given to B vs b (cf h vs H and k)? |
Currently, the spec only support 'B', not 'b'- Neither do we currently support requesting of 'a' If we consider adding support for requesting 'b', we should consider together with how we support 'a'. |
Initial set of tests in tc39/test262#2194 |
This achieved consensus from TC39 and Intl meetings in June 2019 |
@anba - thanks for your comments. |
One spec text question: The spec currently codifies a format as having two subtypes:
If the user requests a certain width for |
if you specify a non-zero value for fractional second digits, and only that, you also get the
Does that seem strange to anyone else? As an author I found that a little surprising.. |
@FrankYFTang I could misunderstand but I don't think this actually answers @leobalter's question. I could be wrong, but I had a similar q which was: Could we add some short prose or example that describes some (basic) idea or example "what is a dayPeriod" and "what do these possible values mean" (or a pointer to where they come from if that is better)? |
That's what I meant, thanks @bkardell! I liked the examples in the PR and I'd like to transfer some of the reasoning of dayPeriod to the ECMA-402 text. |
It seems to me like these underlying data issues should probably be fixed before we consider this PR "done"; I don't know if it makes sense to ship this to web developers while it gives such strange output. I agree with others in this thread that it'd be helpful to have more motivating examples documented. (I'm not sure where in applications you want to use the longer English form, for example, or if that's more included out of completeness/consistency.) |
The resolution to #394 will guide the behavior we want to specify for the above edge cases in this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://tc39.es/ecma402/#table-datetimeformat-tolocaltime-record needs to be updated. Not sure how easy that's going to be, because most other fields in that table are tied to ECMA-262 abstract operations, but dayPeriod
doesn't have any matching operation we can use here.
@@ -514,6 +519,9 @@ <h1>Internal slots</h1> | |||
<li>month, day</li> | |||
<li>hour, minute, second</li> | |||
<li>hour, minute</li> | |||
<li>dayPeriod, hour</li> | |||
<li>dayPeriod, hour, minute, second</li> | |||
<li>dayPeriod, hour, minute</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a good idea what's the most reasonable minimum subset for day-period display should be. So someone with more background in internalisation/localisation is probably a better reviewer for this specific part.
spec/datetimeformat.html
Outdated
@@ -514,6 +519,9 @@ <h1>Internal slots</h1> | |||
<li>month, day</li> | |||
<li>hour, minute, second</li> | |||
<li>hour, minute</li> | |||
<li>dayPeriod, hour</li> | |||
<li>dayPeriod, hour, minute, second</li> | |||
<li>dayPeriod, hour, minute</li> | |||
</ul> | |||
Each of the records must also have a pattern field, whose value is a String value that contains for each of the date and time format component fields of the record a substring starting with `"{"`, followed by the name of the field, followed by `"}"`. If the record has an hour field, it must also have a pattern12 field, whose value is a String value that, in addition to the substrings of the pattern field, contains a substring `"{ampm}"`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part seems problematic, doesn't it? The current spec requires a pattern12
field with an "{ampm}"
substring for any record which has an hour field. But I don't see how this should work with day-period, because then the record must contain day-period and an am/pm marker, which doesn't really make sense, does it?
For example I currently get in SpiderMonkey with the day-period patch enabled:
js> new Intl.DateTimeFormat("en", {hour:"numeric", dayPeriod:"long"}).format()
"1 in the afternoon"
But the current spec text kind of implies the output should rather be:
js> new Intl.DateTimeFormat("en", {hour:"numeric", dayPeriod:"long"}).format()
"1 PM in the afternoon"
And https://unicode.org/reports/tr35/tr35-dates.html#availableFormats_appendItems also seems to disallow using "B" and "a" in a single skeleton:
Only one field of each type is allowed; that is, "Hh" is not valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch; I agree we should fix this. Do you have an idea for wording which would capture that same constraint as CLDR skeletons have?
Day period should probably just not be mentioned at all in |
Also: Do we worry about users having to explicitly set |
Is this PR blocking on landing for #394 to land first? If so, that seems a little unfair, since that issue affects basically everything in Intl.DateTimeFormat. |
@anba I like your suggestion in #346 (comment) . Would you be interested in writing a patch to add to this PR which does that? For #346 (comment) , could you explain what you mean (e.g., give a case where the result would be unexpectedly not useful)? |
For locales defaulting to a 24-hour-cycle, for (let locale of ["en", "de", "fr", "es"]) {
console.log(`locale = ${locale}`);
for (let hour12 of [undefined, true, false]) {
console.log(` hour12 = ${hour12}:`);
let dtf = new Intl.DateTimeFormat(locale, {hour12, hour: "numeric", dayPeriod: "long", timeZone: "UTC"});
for (let date of [new Date("2020-01-01T06:00Z"), new Date("2020-01-01T12:00Z"), new Date("2020-01-01T18:00Z"), new Date("2020-01-01T24:00Z")]) {
console.log(` ${dtf.format(date)}`);
}
}
} Prints in Firefox Nightly:
|
Note that JSC |
@FrankYFTang @sffc please help me recapping this one, is anything pending here before merging this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I applied minor editorial fixes and this is ready to go
The current wording requires to output strings like "12 pm noon", because "ampm" is always required in pattern12 strings. So accept at least one of "ampm" or "dayPeriod". See also the review comments in tc39#346. Note: - "ampm" and "dayPeriod" are probably not both present in a pattern, but UTS 35 doesn't seem to forbid this. - Added the same change to [[styles]], even though no CLDR locale currently use both "ampm" and "dayPeriod". (There are some special cases, though. Cf. "my" locale.)
No description provided.