tc39 / proposal-intl-duration-format

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

GetDurationUnitOptions: Always throw when "numeric" sub-seconds are used with display "always" #155

Closed anba closed 9 months ago

anba commented 1 year ago

Milliseconds, microseconds, and nanoseconds throw when the previous unit's style is numeric-like and their own style is "numeric" and their display is "always". I think we should always throw when "numeric" is used with "always" for sub-seconds, irrespective of the previous unit's style, because the currently allowed option combinations will likely lead to user confusion because the results seem unexpected.

From a user's perspective:

js> new Intl.DurationFormat("en", {millisecondsDisplay:"always"}).format({milliseconds: 1})
"1 ms"
js> new Intl.DurationFormat("en", {millisecondsDisplay:"always"}).format({milliseconds: 0})
"0 ms"
js> new Intl.DurationFormat("en", {millisecondsDisplay:"always"}).format({seconds: 1, milliseconds: 1})
"1 sec, 1 ms"
js> new Intl.DurationFormat("en", {millisecondsDisplay:"always"}).format({seconds: 1, milliseconds: 0})
"1 sec, 0 ms"

So clearly millisecondsDisplay:"always" means that the milliseconds amount is always displayed, even when it's zero, right?

What if the user wants to display the milliseconds amount without the "ms" unit string? I guess they will try to use milliseconds: "numeric":

js> new Intl.DurationFormat("en", {millisecondsDisplay:"always", milliseconds:"numeric"}).format({milliseconds: 1})
"0.001 sec"
js> new Intl.DurationFormat("en", {millisecondsDisplay:"always", milliseconds:"numeric"}).format({milliseconds: 0})
""
js> new Intl.DurationFormat("en", {millisecondsDisplay:"always", milliseconds:"numeric"}).format({seconds: 1, milliseconds: 1})
"1.001 sec"
js> new Intl.DurationFormat("en", {millisecondsDisplay:"always", milliseconds:"numeric"}).format({seconds: 1, milliseconds: 0})
"1 sec"

These results will likely be confusing to the user. millisecondsDisplay:"always" is apparently completely ignored and either only seconds or an empty string is returned. (The results are with #150 applied.)


Proposed changes:

After current step 3, insert:

  1. Else if style is "numeric" and unit is one of "milliseconds", "microseconds", or "nanoseconds", then   a. Set displayDefault to "auto".

After current step 6, insert:

  1. If style is "numeric" and display is "always" and unit is one of "milliseconds", "microseconds", or "nanoseconds", then   a. Throw a RangeError exception.

And remove current step 6.c.


See also #139, #142, and #148.

sffc commented 1 year ago

@ben-allen or @ryzokuken, please investigate this and bring it to the floor with a proposal at an upcoming TG2 meeting.