Skip to content
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

Decide if upcoming Temporal.Duration limits should have an impact on DurationFormat #157

Open
anba opened this issue Jun 12, 2023 · 2 comments
Assignees
Labels
consensus We reached a consensus in a discussion meeting, through email or the issue discussion

Comments

@anba
Copy link
Contributor

anba commented Jun 12, 2023

There are plans to limit Temporal.Duration values, details are still TBD. But we still need to decide if these limits should have an impact on Intl.DurationFormat.

The exact same issue was already discussed in #110, but that was before Temporal decided to reduce precision for their Temporal.Duration. Do we need to revisit #110?

For example I'm currently using the following BigInt-based approach to correctly implement PartitionDurationFormatPattern, steps 4.j.iv.1-3:

// Implementation for PartitionDurationFormatPattern 4.j.iv.1, similar functions are needed for 4.j.iv.2-3.
function DurationToFractionalSeconds(duration) {
  // Directly return seconds when no sub-seconds are present.
  if (
    duration.milliseconds === 0 &&
    duration.microseconds === 0 &&
    duration.nanoseconds === 0
  ) {
    return duration.seconds;
  }

  // Otherwise compute the overall amount of nanoseconds using BigInt to avoid
  // loss of precision.
  var ns_sec = NumberToBigInt(duration.seconds) * 1_000_000_000n;
  var ns_ms = NumberToBigInt(duration.milliseconds) * 1_000_000n;
  var ns_us = NumberToBigInt(duration.microseconds) * 1_000n;
  var ns = ns_sec + ns_ms + ns_us + NumberToBigInt(duration.nanoseconds);

  // Split the nanoseconds amount into seconds and sub-seconds.
  var q = ns / 1_000_000_000n;
  var r = ns % 1_000_000_000n;

  // Pad sub-seconds, without any leading negative sign, to nine digits.
  if (r < 0) {
    r = -r;
  }
  r = callFunction(String_pad_start, ToString(r), 9, "0");

  // Return seconds with fractional part as a decimal string.
  return `${q}.${r}`;
}

This approach ensures the precise results are computed for inputs like:

let df = new Intl.DurationFormat("en", {seconds: "numeric", fractionalDigits: 9});

// "10,000,000.000000002" with Number semantics, because
// 10_000_000 + (1 / 1_000_000_000) === 10000000.000000002.
assertEq(
  df.format({seconds: 10_000_000, nanoseconds: 1}),
  "10,000,000.000000001"
);

// "9,007,199,254,740,992.000000000" with Number semantics, because
// Number.MAX_SAFE_INTEGER + 2 === 9007199254740992.
assertEq(
  df.format({seconds: Number.MAX_SAFE_INTEGER, milliseconds: 2000}),
  "9,007,199,254,740,993.000000000"
);

Also see #110 and #151.

@sffc
Copy link
Collaborator

sffc commented Jun 12, 2023

If we restricted the permissible values to integer-valued Numbers less than Number.MAX_SAFE_INTEGER, then all the math should be doable in int64 space.

Right now it looks like we have integer-valued Numbers but they can exceed MAX_SAFE_INTEGER.

anba added a commit to anba/test262 that referenced this issue Aug 23, 2023
`Intl.DurationFormat` is currently spec'ed to use unlimited precision.

See: tc39/proposal-intl-duration-format#157
@sffc sffc added the Meeting Discussion Need to be discussed in one of the upcoming meetings label Aug 23, 2023
@sffc
Copy link
Collaborator

sffc commented Aug 23, 2023

@ben-allen or @ryzokuken please bring this to the floor in an upcoming TG2 call.

anba added a commit to anba/test262 that referenced this issue Aug 25, 2023
`Intl.DurationFormat` is currently spec'ed to use unlimited precision.

See: tc39/proposal-intl-duration-format#157
Ms2ger pushed a commit to anba/test262 that referenced this issue Aug 28, 2023
`Intl.DurationFormat` is currently spec'ed to use unlimited precision.

See: tc39/proposal-intl-duration-format#157
Ms2ger pushed a commit to tc39/test262 that referenced this issue Aug 28, 2023
`Intl.DurationFormat` is currently spec'ed to use unlimited precision.

See: tc39/proposal-intl-duration-format#157
@sffc sffc added consensus We reached a consensus in a discussion meeting, through email or the issue discussion and removed Meeting Discussion Need to be discussed in one of the upcoming meetings labels Nov 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consensus We reached a consensus in a discussion meeting, through email or the issue discussion
Projects
None yet
Development

No branches or pull requests

4 participants