Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

DateTimeFormat.prototype.resolveOptions may show fewer resolved options than present in formatted range #22

Closed
anba opened this issue May 27, 2020 · 6 comments

Comments

@anba
Copy link

anba commented May 27, 2020

Example:

js> var dtf = new Intl.DateTimeFormat("en", {hour: "numeric", timeZone: "UTC"})
js> dtf.resolvedOptions()
({locale:"en", calendar:"gregory", numberingSystem:"latn", timeZone:"UTC", hourCycle:"h12", hour12:true, hour:"numeric"})
js> dtf.formatRange(0, 24*60*60*1000)                                                               
"1/1/1970, 12 AM \u2013 1/2/1970, 12 AM"

The resolved options imply that only the "hour" date-time field is used, but the formatted range contains additional date-time fields.

See also #21.

@FrankYFTang
Copy link
Contributor

The resolvedOptions should bind to the object itself, not the result fo formatRange which may have different fields depending on the range you call the formatRange, which we do not know what they are when we create the object. I think we should not change the output of resolvedOptions since we do not have the information of what two dates until the formatRange is called.

@anba
Copy link
Author

anba commented Jul 14, 2020

The implementation constraints due to ICU resp. CLDR resp. ultimately UTS 35 are probably clear for implementers, but I don't really know what users will expect for the above case. They could expect that the output string only contains hours, for example when trying to format something like 10 PM - 6 AM. (*)

And as you've mentioned, the date-time fields in the output string depend on the input range. But that also means there's no way for users to determine upfront which fields are going to be used, which makes the whole feature kind of a black box.

I don't have a clear suggestion on how to move forward, the proposal champions and reviewers should evaluate possible options.


(*) There's this one weird trick you can use get that output: For whatever reason ICU no longer returns year, month, and day fields when the dates are in different eras:

js> var dtf = new Intl.DateTimeFormat("en", {hour: "numeric", timeZone: "UTC"})   
js> dtf.formatRange(new Date("-000001-01-01T22:00Z"), new Date("+000001-01-01T06:00Z"))
"10 PM \u2013 6 AM"

It's unlikely someone stumbles across this issue for the Gregorian calendar, but maybe more likely to be noticeable for other calendars like the Japanese calendar:

js> var dtf = new Intl.DateTimeFormat("en", {hour: "numeric", timeZone: "UTC"})               
js> dtf.formatRange(new Date("2010-01-01"), new Date("2020-01-01"))             
"1/1/2010, 12 AM \u2013 1/1/2020, 12 AM"
js> var dtf = new Intl.DateTimeFormat("en-u-ca-japanese", {hour: "numeric", timeZone: "UTC"})
js> dtf.formatRange(new Date("2010-01-01"), new Date("2020-01-01"))                           
"12 AM \u2013 12 AM"

@fabalbon
Copy link
Member

I think that there may be two different (but closely related) issues:

  1. Should the resolved options contain the additional date-time fields used when formatting a date range?

  2. There is no way for the user to determine upfront which fields are going to be displayed in the formatted string.


1)

I agree with Frank that the resolvedOptions should bind to the formatter object itself and not to the result of formatRange().

One of the reasons for this is that the current options returned by resolvedOptions() are computed when initializing the formatter and are used when selecting the best date pattern and the best set of date-range patterns. It is true that some of those date-range patterns may contain additional calendar fields not present in the resolvedOptions, but these fields are not relevant when initializing the formatter and do not “characterize” the formatter, instead they are only used to properly format some date-ranges.

Together with this, from a practical point of view, a second issue is that there doesn’t seem to be a straightforward way to include the additional calendar fields in resolvedOptions() because they are only known in formatRange(). It might be possible to either extend the current API or update resolveOptions() to return these additional calendar fields, but it is not clear to me if the gains of doing so are higher than the additional complexity this solution would bring.


2)

I agree that not having a way for the users to determine upfront which fields are going to be displayed or to control this makes this feature as some kind of blackbox. We discussed this during the last 402 working group meeting and examples such as 10 pm - 6 am were brought up.

One idea to potentially support this is to add an option which would allow users to indicate that they want to restrict the calendar fields used when formatting the date range to either a defined subset or to the options in the resolved options.

Now, currently ICU date-range formatting does act as a blackbox which means that changing this behavior will probably require an ICU/CLDR update so that the new behavior can be supported by implementers who use ICU.

Given this, the consensus at the last 402 working group meeting was to keep the current behavior as is and propose an update or an additional option on a follow-up proposal once ICU is updated.

Any thoughts?


There's this one weird trick you can use get that output: For whatever reason ICU no longer returns year, month, and day fields when the dates are in different eras

This behavior seems to be unexpected and it looks like an ICU bug.

@FrankYFTang
Copy link
Contributor

(*) There's this one weird trick you can use get that output: For whatever reason ICU no longer returns year, month, and day fields when the dates are in different eras:
I file the issue in https://unicode-org.atlassian.net/browse/ICU-21222 . That is inconsistent.

@fabalbon
Copy link
Member

Conclusion from the ECMA-402 meeting (2020-10-08):

Issue 1)
The current resolvedOptions would not allow us to return the additional date-time fields added by range formatting. We should not block the current proposal, but should explore this in a followup proposal. Alternatives to resolve this could be to add an extra API or to extend formateRangeToParts to return this information (by adding an additional field that indicates the calendar field's width).

Issue 2)
We should keep the current behavior for this proposal, as we are formatting JS dates (which are timestamps). We can add support to drop fields when supporting Temporal (e.g. formatting a range of Temporal.Times).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants