Skip to content

Commit

Permalink
[JSC] fractionalDigits of Intl.DurationFormat should be treated a…
Browse files Browse the repository at this point in the history
…s at most 9 digits if it is omitted

https://bugs.webkit.org/show_bug.cgi?id=274974

Reviewed by Yusuke Suzuki.

According to the spec[1], if the `fractionalDigits` option of `Intl.DurationFormat` is omitted, it
should be treated as at most 9 digits. However, in the current JSC, it is treated as exact 0 digits.

The README of the proposal repository[2] states the following:
> If this option is omitted, only nonzero decimals will be displayed and trailing zeroes will be omitted.

This patch changes to treat it as at most 9 digits, using the ICU's Fraction Precision notation[3].

[1]: https://tc39.es/proposal-intl-duration-format/#sec-partitiondurationformatpattern ( 4.f.ii.1.b )
[2]: https://github.com/tc39/proposal-intl-duration-format#parameters
[3]: https://github.com/unicode-org/icu/blob/main/docs/userguide/format_parse/numbers/skeletons.md#fraction-precision

* JSTests/stress/intl-durationformat-digital.js:
(Intl.DurationFormat.shouldBeOneOf.fmt.format):
(Intl.DurationFormat.shouldBeOneOf):
* JSTests/test262/expectations.yaml:
* Source/JavaScriptCore/runtime/IntlDurationFormat.cpp:
(JSC::collectElements):

Canonical link: https://commits.webkit.org/279632@main
  • Loading branch information
sosukesuzuki authored and Constellation committed Jun 3, 2024
1 parent 5290e07 commit d0e99df
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 27 deletions.
12 changes: 6 additions & 6 deletions JSTests/stress/intl-durationformat-digital.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,39 @@ if (Intl.DurationFormat) {
style: 'digital'
});
shouldBeOneOf(fmt.format({ years: 1, months: 2, weeks: 3, days: 4, hours: 10, minutes: 34, seconds: 33, milliseconds: 32 }), [
`1 yr, 2 mths, 3 wks, 4 days, 10.34.33`,
`1 yr, 2 mths, 3 wks, 4 days, 10.34.33,032`,
]);
}
{
var fmt = new Intl.DurationFormat('en-DK-u-ca-buddhist', {
style: 'digital'
});
shouldBeOneOf(fmt.format({ years: 1, months: 2, weeks: 3, days: 4, hours: 10, minutes: 34, seconds: 33, milliseconds: 32 }), [
`1 yr, 2 mths, 3 wks, 4 days, 10.34.33`,
`1 yr, 2 mths, 3 wks, 4 days, 10.34.33,032`,
]);
}
{
var fmt = new Intl.DurationFormat('en-DK-u-nu-hanidec', {
style: 'digital'
});
shouldBeOneOf(fmt.format({ years: 1, months: 2, weeks: 3, days: 4, hours: 10, minutes: 34, seconds: 33, milliseconds: 32 }), [
`一 yr, 二 mths, 三 wks, 四 days, 一〇:三四:三三`,
`一 yr, 二 mths, 三 wks, 四 days, 一〇:三四:三三,〇三二`,
]);
}
{
var fmt = new Intl.DurationFormat('en', {
style: 'digital'
});
shouldBeOneOf(fmt.format({ years: 1, months: 2, weeks: 3, days: 4, hours: 10, minutes: 34, seconds: 33, milliseconds: 32 }), [
`1 yr, 2 mths, 3 wks, 4 days, 10:34:33`,
`1 yr, 2 mths, 3 wks, 4 days, 10:34:33.032`,
]);
}
{
var fmt = new Intl.DurationFormat('en', {
style: 'digital'
});
shouldBeOneOf(fmt.format({ years: 1, months: 2, weeks: 3, days: 4, hours: 10, minutes: 34, seconds: 33, milliseconds: 32 }), [
`1 yr, 2 mths, 3 wks, 4 days, 10:34:33`,
`1 yr, 2 mths, 3 wks, 4 days, 10:34:33.032`,
]);
}
{
Expand Down Expand Up @@ -114,7 +114,7 @@ if (Intl.DurationFormat) {
});

shouldBeOneOf(fmt.format({ hours: 10, minutes: 10, milliseconds: 32}), [
`10:10:00`,
`10:10:00.032`,
]);
}
{
Expand Down
24 changes: 6 additions & 18 deletions JSTests/test262/expectations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,9 +1026,6 @@ test/intl402/DateTimeFormat/timezone-legacy-non-iana.js:
test/intl402/DateTimeFormat/timezone-not-canonicalized.js:
default: 'Test262Error: Expected SameValue(«Asia/Calcutta», «Asia/Kolkata») to be true'
strict mode: 'Test262Error: Expected SameValue(«Asia/Calcutta», «Asia/Kolkata») to be true'
test/intl402/DurationFormat/prototype/format/fractions-of-subsecond-units-en.js:
default: 'Test262Error: DurationFormat output when microseconds first "numeric" unit Expected SameValue(«3 sec, 444 ms», «3 sec, 444.055006 ms») to be true'
strict mode: 'Test262Error: DurationFormat output when microseconds first "numeric" unit Expected SameValue(«3 sec, 444 ms», «3 sec, 444.055006 ms») to be true'
test/intl402/DurationFormat/prototype/format/negative-duration-style-default-en.js:
default: 'Test262Error: DurationFormat format output using default style option Expected SameValue(«-1 yr, -2 mths, -3 wks, -3 days, -4 hr, -5 min, -6 sec, -7 ms, -8 μs, -9 ns», «-1 yr, 2 mths, 3 wks, 3 days, 4 hr, 5 min, 6 sec, 7 ms, 8 μs, 9 ns») to be true'
strict mode: 'Test262Error: DurationFormat format output using default style option Expected SameValue(«-1 yr, -2 mths, -3 wks, -3 days, -4 hr, -5 min, -6 sec, -7 ms, -8 μs, -9 ns», «-1 yr, 2 mths, 3 wks, 3 days, 4 hr, 5 min, 6 sec, 7 ms, 8 μs, 9 ns») to be true'
Expand All @@ -1051,8 +1048,8 @@ test/intl402/DurationFormat/prototype/format/negative-duration-with-leading-zero
default: 'Test262Error: DurationFormat format output using short style option Expected SameValue(«0 hr, -1 sec», «-0 hr, 1 sec») to be true'
strict mode: 'Test262Error: DurationFormat format output using short style option Expected SameValue(«0 hr, -1 sec», «-0 hr, 1 sec») to be true'
test/intl402/DurationFormat/prototype/format/negative-durationstyle-digital-en.js:
default: 'Test262Error: DurationFormat format output using digital style option Expected SameValue(«-1 yr, -2 mths, -3 wks, -3 days, -4:-05:-06», «-1 yr, 2 mths, 3 wks, 3 days, 4:05:06.007008009») to be true'
strict mode: 'Test262Error: DurationFormat format output using digital style option Expected SameValue(«-1 yr, -2 mths, -3 wks, -3 days, -4:-05:-06», «-1 yr, 2 mths, 3 wks, 3 days, 4:05:06.007008009») to be true'
default: 'Test262Error: DurationFormat format output using digital style option Expected SameValue(«-1 yr, -2 mths, -3 wks, -3 days, -4:-05:-06.007008009», «-1 yr, 2 mths, 3 wks, 3 days, 4:05:06.007008009») to be true'
strict mode: 'Test262Error: DurationFormat format output using digital style option Expected SameValue(«-1 yr, -2 mths, -3 wks, -3 days, -4:-05:-06.007008009», «-1 yr, 2 mths, 3 wks, 3 days, 4:05:06.007008009») to be true'
test/intl402/DurationFormat/prototype/format/negative-durationstyle-long-en.js:
default: 'Test262Error: DurationFormat format output using long style option Expected SameValue(«-1 year, -2 months, -3 weeks, -3 days, -4 hours, -5 minutes, -6 seconds, -7 milliseconds, -8 microseconds, -9 nanoseconds», «-1 year, 2 months, 3 weeks, 3 days, 4 hours, 5 minutes, 6 seconds, 7 milliseconds, 8 microseconds, 9 nanoseconds») to be true'
strict mode: 'Test262Error: DurationFormat format output using long style option Expected SameValue(«-1 year, -2 months, -3 weeks, -3 days, -4 hours, -5 minutes, -6 seconds, -7 milliseconds, -8 microseconds, -9 nanoseconds», «-1 year, 2 months, 3 weeks, 3 days, 4 hours, 5 minutes, 6 seconds, 7 milliseconds, 8 microseconds, 9 nanoseconds») to be true'
Expand All @@ -1069,23 +1066,14 @@ test/intl402/DurationFormat/prototype/format/numeric-hour-with-zero-minutes-and-
default: 'Test262Error: Duration is {"hours":0,"minutes":0,"seconds":1} Expected SameValue(«0, 01», «0:00:01») to be true'
strict mode: 'Test262Error: Duration is {"hours":0,"minutes":0,"seconds":1} Expected SameValue(«0, 01», «0:00:01») to be true'
test/intl402/DurationFormat/prototype/format/precision-exact-mathematical-values.js:
default: 'Test262Error: Duration is {"seconds":10000000,"nanoseconds":1} Expected SameValue(«0:00:10,000,000», «0:00:10,000,000.000000001») to be true'
strict mode: 'Test262Error: Duration is {"seconds":10000000,"nanoseconds":1} Expected SameValue(«0:00:10,000,000», «0:00:10,000,000.000000001») to be true'
test/intl402/DurationFormat/prototype/format/style-digital-en.js:
default: 'Test262Error: Assert DurationFormat format output using digital style option Expected SameValue(«1 yr, 2 mths, 3 wks, 3 days, 4:05:06», «1 yr, 2 mths, 3 wks, 3 days, 4:05:06.007008009») to be true'
strict mode: 'Test262Error: Assert DurationFormat format output using digital style option Expected SameValue(«1 yr, 2 mths, 3 wks, 3 days, 4:05:06», «1 yr, 2 mths, 3 wks, 3 days, 4:05:06.007008009») to be true'
test/intl402/DurationFormat/prototype/format/style-digital-fractionalDigits-undefined-en.js:
default: 'Test262Error: format output with nanosecond digits and fractionalDigits: undefined using digital style option Expected SameValue(«1:22:33», «1:22:33.111222333») to be true'
strict mode: 'Test262Error: format output with nanosecond digits and fractionalDigits: undefined using digital style option Expected SameValue(«1:22:33», «1:22:33.111222333») to be true'
test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-digital-en.js:
default: 'Test262Error: Using style : digital: length Expected SameValue(«5», «7») to be true'
strict mode: 'Test262Error: Using style : digital: length Expected SameValue(«5», «7») to be true'
default: 'Test262Error: Duration is {"seconds":10000000,"nanoseconds":1} Expected SameValue(«0:00:10,000,000.000000002», «0:00:10,000,000.000000001») to be true'
strict mode: 'Test262Error: Duration is {"seconds":10000000,"nanoseconds":1} Expected SameValue(«0:00:10,000,000.000000002», «0:00:10,000,000.000000001») to be true'
test/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-default-en.js:
default: 'Test262Error: Using style : default: length Expected SameValue(«49», «40») to be true'
strict mode: 'Test262Error: Using style : default: length Expected SameValue(«49», «40») to be true'
test/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-digital-en.js:
default: 'Test262Error: Using style : digital: length Expected SameValue(«28», «24») to be true'
strict mode: 'Test262Error: Using style : digital: length Expected SameValue(«28», «24») to be true'
default: 'Test262Error: Using style : digital: length Expected SameValue(«30», «24») to be true'
strict mode: 'Test262Error: Using style : digital: length Expected SameValue(«30», «24») to be true'
test/intl402/DurationFormat/prototype/formatToParts/negative-duration-formatToParts-style-long-en.js:
default: 'Test262Error: Using style : long: length Expected SameValue(«49», «40») to be true'
strict mode: 'Test262Error: Using style : long: length Expected SameValue(«49», «40») to be true'
Expand Down
10 changes: 7 additions & 3 deletions Source/JavaScriptCore/runtime/IntlDurationFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,13 @@ static Vector<Element> collectElements(JSGlobalObject* globalObject, const IntlD
// https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#fraction-precision
skeletonBuilder.append(" ."_s);

unsigned fractionalDigits = durationFormat->fractionalDigits() == fractionalDigitsUndefinedValue ? 0 : durationFormat->fractionalDigits();
for (unsigned i = 0; i < fractionalDigits; ++i)
skeletonBuilder.append('0');
unsigned fractionalDigits = durationFormat->fractionalDigits();
if (fractionalDigits == fractionalDigitsUndefinedValue)
skeletonBuilder.append("#########"_s);
else {
for (unsigned i = 0; i < fractionalDigits; ++i)
skeletonBuilder.append('0');
}
done = true;
}
break;
Expand Down

0 comments on commit d0e99df

Please sign in to comment.