Skip to content

Commit 19a3947

Browse files
committed
fix(unstable/temporal): respect locale in Duration.prototype.toLocaleString
1 parent 5ca47ee commit 19a3947

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

runtime/js/99_main.js

+54
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const {
3737
ObjectHasOwn,
3838
ObjectKeys,
3939
ObjectGetOwnPropertyDescriptor,
40+
ObjectGetOwnPropertyDescriptors,
4041
ObjectPrototypeIsPrototypeOf,
4142
ObjectSetPrototypeOf,
4243
PromisePrototypeThen,
@@ -45,6 +46,7 @@ const {
4546
Symbol,
4647
SymbolIterator,
4748
TypeError,
49+
uncurryThis,
4850
} = primordials;
4951
const {
5052
isNativeError,
@@ -459,6 +461,51 @@ function exposeUnstableFeaturesForWindowOrWorkerGlobalScope(unstableFeatures) {
459461
}
460462
}
461463

464+
function shimTemporalDurationToLocaleString() {
465+
const DurationFormat = Intl.DurationFormat;
466+
if (!DurationFormat) {
467+
// Intl.DurationFormat can be disabled with --v8-flags=--no-harmony-intl-duration-format
468+
return;
469+
}
470+
const DurationFormatPrototype = DurationFormat.prototype;
471+
const formatDuration = uncurryThis(DurationFormatPrototype.format);
472+
473+
const Duration = Temporal.Duration;
474+
const DurationPrototype = Duration.prototype;
475+
const desc = ObjectGetOwnPropertyDescriptors(DurationPrototype);
476+
const assertDuration = uncurryThis(desc.toLocaleString.value);
477+
const getYears = uncurryThis(desc.years.get);
478+
const getMonths = uncurryThis(desc.months.get);
479+
const getWeeks = uncurryThis(desc.weeks.get);
480+
const getDays = uncurryThis(desc.days.get);
481+
const getHours = uncurryThis(desc.hours.get);
482+
const getMinutes = uncurryThis(desc.minutes.get);
483+
const getSeconds = uncurryThis(desc.seconds.get);
484+
const getMilliseconds = uncurryThis(desc.milliseconds.get);
485+
const getMicroseconds = uncurryThis(desc.microseconds.get);
486+
const getNanoseconds = uncurryThis(desc.nanoseconds.get);
487+
488+
ObjectAssign(DurationPrototype, {
489+
toLocaleString(locales = undefined, options) {
490+
assertDuration(this);
491+
const durationFormat = new DurationFormat(locales, options);
492+
const duration = {
493+
years: getYears(this),
494+
months: getMonths(this),
495+
weeks: getWeeks(this),
496+
days: getDays(this),
497+
hours: getHours(this),
498+
minutes: getMinutes(this),
499+
seconds: getSeconds(this),
500+
milliseconds: getMilliseconds(this),
501+
microseconds: getMicroseconds(this),
502+
nanoseconds: getNanoseconds(this),
503+
};
504+
return formatDuration(durationFormat, duration);
505+
},
506+
});
507+
}
508+
462509
// NOTE(bartlomieju): remove all the ops that have already been imported using
463510
// "virtual op module" (`ext:core/ops`).
464511
const NOT_IMPORTED_OPS = [
@@ -821,6 +868,11 @@ function bootstrapMainRuntime(runtimeOptions, warmup = false) {
821868
});
822869
delete globalThis.Temporal.Now.timeZone;
823870
}
871+
872+
if (new Temporal.Duration().toLocaleString("en-US") !== "PT0S") {
873+
throw "V8 supports Temporal.Duration.prototype.toLocaleString now, no need to shim it";
874+
}
875+
shimTemporalDurationToLocaleString();
824876
}
825877

826878
// Setup `Deno` global - we're actually overriding already existing global
@@ -1024,6 +1076,8 @@ function bootstrapWorkerRuntime(
10241076
});
10251077
delete globalThis.Temporal.Now.timeZone;
10261078
}
1079+
1080+
shimTemporalDurationToLocaleString();
10271081
}
10281082

10291083
// Setup `Deno` global - we're actually overriding already existing global

tests/specs/run/unstable_temporal_api_patch/main.out

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ iso8601
55
UTC
66
undefined
77
undefined
8+
1 day, 6 hr, 30 min

tests/specs/run/unstable_temporal_api_patch/main.ts

+3
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ console.log(zoned.timeZoneId);
99
console.log(zoned.calendar);
1010
// @ts-expect-error: undefined check
1111
console.log(zoned.timeZone);
12+
13+
const duration = Temporal.Duration.from("P1DT6H30M");
14+
console.log(duration.toLocaleString("en-US"));

0 commit comments

Comments
 (0)