tc39 / proposal-intl-duration-format

https://tc39.es/proposal-intl-duration-format
MIT License
165 stars 18 forks source link

Create with {"microseconds":"fractional"} cause RangeError #195

Closed FrankYFTang closed 5 months ago

FrankYFTang commented 5 months ago

The following, according to the current spec, will throw RangeError

let a = new Intl.DurationFormat("en", {"microseconds":"fractional"});

Is that desireable? The constructor will call f. Let unitOptions be ? GetDurationUnitOptions(unit, options, style, valueList, digitalBase, prevStyle).

with

GetDurationUnitOptions("years"...)
GetDurationUnitOptions("months"...)
GetDurationUnitOptions("weeks"...)
GetDurationUnitOptions("days"...)
GetDurationUnitOptions("hours"...)
GetDurationUnitOptions("minutes"...)
GetDurationUnitOptions("seconds"...)
then ...
GetDurationUnitOptions("milliseconds", {"microseconds":"fractional"}, "short", 
« "long", "short", "narrow", "fractional" » , "numeric", "short")
then ...
GetDurationUnitOptions("microseconds", {"microseconds":"fractional"}, "short", 
« "long", "short", "narrow", "fractional" » , "fractional", "short")

then inside GetDurationUnitOptions after

1. Let style be ? GetOption(options, unit, string, stylesList, undefined).

style is "fractional" and

2. Let displayDefault be "always".

then after

6. Let display be ? GetOption(options, displayField, string, « "auto", "always" », displayDefault).

display is "always" because displayDefault is "always"

and then

7. If display is "always" and style is "fractional", then
a. Throw a RangeError exception.

will throw.

But is this desired?

FrankYFTang commented 5 months ago

The test it will fail

https://github.com/tc39/test262/blob/main/test/intl402/DurationFormat/prototype/format/fractions-of-subsecond-units-en.js
@anba @sffc @ben-allen @ryzokuken

sffc commented 5 months ago

I think it will always hit one of the several

1. Set displayDefault to "auto".

Also, "fractional" is spec-internal. It can't be specified in the API. It is always "numeric" in the API.

sffc commented 5 months ago

Also, "fractional" is spec-internal. It can't be specified in the API. It is always "numeric" in the API.

Or not: https://github.com/tc39/proposal-intl-duration-format/issues/196

FrankYFTang commented 5 months ago

And in the current spec, all of the following will throw RangeError

let a1 = new Intl.DurationFormat("en", {"milliseconds":"numeric"});
let a2 = new Intl.DurationFormat("en", {"microseconds":"numeric"});
let a3 = new Intl.DurationFormat("en", {"nanoseconds":"numeric"});
let a4 = new Intl.DurationFormat("en", {"milliseconds":"fractional"});
let a5 = new Intl.DurationFormat("en", {"microseconds":"fractional"});
let a6 = new Intl.DurationFormat("en", {"nanoseconds":"fractional"});

a1- a3 will throw RangeError because valuesList for GetDurationUnitOptions are « "long", "short", "narrow", "fractional" » for the case of "milliseconds", "microseconds" and "nanoseconds" and that does not contains "numeric" so GetOption will throw RangeError a4-a6 will throw because Step 7 mentioned above

ben-allen commented 5 months ago

Fixed by https://github.com/tc39/proposal-intl-duration-format/pull/197