1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-18 05:14:21 -05:00

fix(unstable/temporal): respect locale in Duration.prototype.toLocaleString (#27000)

Adds a temporary polyfill for `Duration.prototype.toLocaleString()`
that will be removed once native support in V8 lands.
This commit is contained in:
ud2 2024-12-05 21:55:50 +08:00 committed by GitHub
parent e8d731c05f
commit 25aed5071f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 59 additions and 0 deletions

View file

@ -37,6 +37,7 @@ const {
ObjectHasOwn,
ObjectKeys,
ObjectGetOwnPropertyDescriptor,
ObjectGetOwnPropertyDescriptors,
ObjectPrototypeIsPrototypeOf,
ObjectSetPrototypeOf,
PromisePrototypeThen,
@ -45,6 +46,7 @@ const {
Symbol,
SymbolIterator,
TypeError,
uncurryThis,
} = primordials;
const {
isNativeError,
@ -459,6 +461,51 @@ function exposeUnstableFeaturesForWindowOrWorkerGlobalScope(unstableFeatures) {
}
}
function shimTemporalDurationToLocaleString() {
const DurationFormat = Intl.DurationFormat;
if (!DurationFormat) {
// Intl.DurationFormat can be disabled with --v8-flags=--no-harmony-intl-duration-format
return;
}
const DurationFormatPrototype = DurationFormat.prototype;
const formatDuration = uncurryThis(DurationFormatPrototype.format);
const Duration = Temporal.Duration;
const DurationPrototype = Duration.prototype;
const desc = ObjectGetOwnPropertyDescriptors(DurationPrototype);
const assertDuration = uncurryThis(desc.toLocaleString.value);
const getYears = uncurryThis(desc.years.get);
const getMonths = uncurryThis(desc.months.get);
const getWeeks = uncurryThis(desc.weeks.get);
const getDays = uncurryThis(desc.days.get);
const getHours = uncurryThis(desc.hours.get);
const getMinutes = uncurryThis(desc.minutes.get);
const getSeconds = uncurryThis(desc.seconds.get);
const getMilliseconds = uncurryThis(desc.milliseconds.get);
const getMicroseconds = uncurryThis(desc.microseconds.get);
const getNanoseconds = uncurryThis(desc.nanoseconds.get);
ObjectAssign(DurationPrototype, {
toLocaleString(locales = undefined, options) {
assertDuration(this);
const durationFormat = new DurationFormat(locales, options);
const duration = {
years: getYears(this),
months: getMonths(this),
weeks: getWeeks(this),
days: getDays(this),
hours: getHours(this),
minutes: getMinutes(this),
seconds: getSeconds(this),
milliseconds: getMilliseconds(this),
microseconds: getMicroseconds(this),
nanoseconds: getNanoseconds(this),
};
return formatDuration(durationFormat, duration);
},
});
}
// NOTE(bartlomieju): remove all the ops that have already been imported using
// "virtual op module" (`ext:core/ops`).
const NOT_IMPORTED_OPS = [
@ -821,6 +868,12 @@ function bootstrapMainRuntime(runtimeOptions, warmup = false) {
});
delete globalThis.Temporal.Now.timeZone;
}
// deno-lint-ignore prefer-primordials
if (new Temporal.Duration().toLocaleString("en-US") !== "PT0S") {
throw "V8 supports Temporal.Duration.prototype.toLocaleString now, no need to shim it";
}
shimTemporalDurationToLocaleString();
}
// Setup `Deno` global - we're actually overriding already existing global
@ -1024,6 +1077,8 @@ function bootstrapWorkerRuntime(
});
delete globalThis.Temporal.Now.timeZone;
}
shimTemporalDurationToLocaleString();
}
// Setup `Deno` global - we're actually overriding already existing global

View file

@ -5,3 +5,4 @@ iso8601
UTC
undefined
undefined
1 day, 6 hr, 30 min

View file

@ -9,3 +9,6 @@ console.log(zoned.timeZoneId);
console.log(zoned.calendar);
// @ts-expect-error: undefined check
console.log(zoned.timeZone);
const duration = Temporal.Duration.from("P1DT6H30M");
console.log(duration.toLocaleString("en-US"));