tc39 / proposal-intl-duration-format

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

Format of negative durations #169

Closed anba closed 8 months ago

anba commented 1 year ago
var df = new Intl.DurationFormat("en", {style:"digital"});
console.log(df.format({hours: -1, minutes: -1, seconds: -1}));

This is currently spec'ed to return the string "-1:-01:-01", but I'm not sure if this matches user expectations.

This issue was previously discussed in #29:

But I don't quite follow the discussion in #29:

  1. I don't understand why disallowing mixed signs allowed to close #29.
  2. The current Intl.DurationFormat spec doesn't allow any CLDR/ILD specific duration formatting, because the complete output is defined through Intl.NumberFormat and Intl.ListFormat. So mentioning CLDR/ILD is kind of moot, because we define how to glue the individual components.
sffc commented 1 year ago

Yeah, it is a bug if the spec requires "-1:-01:-01"

Issue #29 was closed when we decided to not allow mixed-sign units. However, bikeshedding the specific formats has not been done yet as far as I know. Hmm.

sffc commented 1 year ago

Seems there are two reasonable ways to display negative durations:

(EDIT: Others added based on discussion)

  1. Only the first unit in display order gets the sign: "-3 days, 2 hours, 1:04"
  2. All units get a sign except for trailing numeric units: "-3 days, -2 hours, -1:04"
  3. All units, even trailing numeric units, get a sign: "-3 days, -2 hours, -1:-04"
  4. Parentheses: "-(3 days, 2 hours, 1:04)"
  5. Keyphrase: "3 days, 2 hours, 1:04 earlier" or "Negative 3 days, 2 hours, 1:04"
  6. Fall back to ISO-8601: "-PT3D2H1M4S"
sffc commented 1 year ago

We should also make sure that we don't allow mixed signs in the formattable object when it is not a Temporal.Duration.

sffc commented 10 months ago

TG2 discussion: https://github.com/tc39/ecma402/blob/master/meetings/notes-2023-10-12.md#format-of-negative-durations

No firm conclusion. A few more options were proposed, which I added to https://github.com/tc39/proposal-intl-duration-format/issues/169#issuecomment-1690712130. I have scheduled this for an upcoming CLDR design call.

sffc commented 10 months ago

Also, @justingrant volunteered to share some use cases here in this thread.

justingrant commented 10 months ago

Here's a few use cases for negative durations to help guide the decision, using plain conversational language rather than computer-ese, to better model how real language works.

Q: How much later, in local time, will it be when my flight arrives in arrive in San Francisco, compared to the local time when it departed Tokyo? A: 6 hours and 35 minutes earlier, because of the time zone change.

Q: How long after this retail store opened was the first sale made yesterday? A: Negative 2 minutes, because the store manager opened the door a few minutes early and and a customer walked in and bought something.

Q: (Manager) How long until you have a PR ready to fix this bug? A: (Engineer) Negative 3 hours, I already fixed it! 😄

Q: How much later were you born than your twin sister? A: 5 minutes before, I'm older!

A trucking company wants to encourage their drivers to arrive on time, or maybe a bit early. So they institute a bonus system where every month the delta between expected arrival times and actual arrival times are summed, and if the result is negative then they're awarded a $1-per-negative-minute bonus up to $100.

Q: (a lawyer's client, angry) You submitted that brief to the wrong judge, and now I lost my case and have to pay $5,000. Are you still going to charge me for writing it? A: (lawyer) I'm so sorry. I'll not only not charge you, but I'll add a negative 10 billable-hour credit to your next invoice to cover my mistake.

The general theme to all of these examples is that negative durations are a possible but often unusual case where the people assumed that the duration would be positive, but sometimes they're negative so nonetheless must be accommodated.

sffc commented 10 months ago

Another use case I encountered a few days ago:

Q: When are the next departures from San Francisco to San José? A: There are departures in -3 min, 17 min, and 37 min


I scheduled this for the CLDR design meeting at 10am on 2023-11-06.

sffc commented 10 months ago

The CLDR committee recommends option 1 as the default fallback behavior with the observation that it works better with narrow and numeric durations, like "-5d 3h 7m". However, CLDR wants to continue this in two lines of work:

  1. Locales should be able to specify their own data for these formats. The form of that data is yet to be designed.
  2. The committee feels that the more dominant use case is the "relative to fixed point in time" format, the third category of duration formating which has also been brought up in earlier threads on this repo.

Also worth noting that some folks on the committee were not convinced that we should support formating of floating negative durations at all, suggesting we throw an exception or similar.

ben-allen commented 10 months ago

Thank you so much for your work with the CLDR folks! Will proceed with option 1 for now, barring other guidance.

re: point 2, I'm increasingly convinced that negative durations, and formatting of negative durations, makes sense because sometimes you want to do math involving durations, and in that context negative durations are useful for the same reason that negative numbers are useful.

Justin's examples (particularly the trucking company one) get at this, but also the contrived example that I keep coming back to is something like:

There's a negative duration involved here, it's something that happens regularly in the world, someone might want to format it, and it's not directly related to any particular fixed point in time.

FrankYFTang commented 4 months ago

The following tests in test262 need to be updated after the landing of the PR

test262/intl402/DurationFormat/prototype/format/negative-duration-style-default-en test262/intl402/DurationFormat/prototype/format/negative-durationstyle-long-en test262/intl402/DurationFormat/prototype/format/negative-durationstyle-digital-en test262/intl402/DurationFormat/prototype/format/negative-durationstyle-narrow-en test262/intl402/DurationFormat/prototype/format/negative-duration-style-short-en test262/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-digital-en test262/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-long-en test262/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-narrow-en test262/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-short-en test262/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-default-en