mirror of
https://github.com/tc39/test262.git
synced 2025-07-22 13:34:38 +02:00
Temporal: Look up getOffsetNanosecondsFor only once when resolving ambiguous datetime
This commit is contained in:
parent
9b8d9cf66c
commit
3a57a424e0
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.duration.compare
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like
|
||||||
|
relativeTo property bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const duration1 = new Temporal.Duration(0, 0, 0, 1);
|
||||||
|
const duration2 = new Temporal.Duration(0, 0, 0, 2);
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
let relativeTo = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
Temporal.Duration.compare(duration1, duration2, {relativeTo: relativeTo});
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
relativeTo = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
Temporal.Duration.compare(duration1, duration2, {relativeTo: relativeTo});
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.duration.prototype.add
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like
|
||||||
|
relativeTo property bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const instance = new Temporal.Duration(1, 0, 0, 1);
|
||||||
|
|
||||||
|
let relativeTo = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo });
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
relativeTo = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo });
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.duration.prototype.round
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like
|
||||||
|
relativeTo property bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const instance = new Temporal.Duration(1, 0, 0, 0, 24);
|
||||||
|
|
||||||
|
let relativeTo = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.round({ largestUnit: "years", relativeTo });
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
relativeTo = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.round({ largestUnit: "years", relativeTo });
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.duration.prototype.subtract
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like
|
||||||
|
relativeTo property bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const instance = new Temporal.Duration(1, 0, 0, 1);
|
||||||
|
|
||||||
|
let relativeTo = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo });
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
relativeTo = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo });
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.duration.prototype.total
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like
|
||||||
|
relativeTo property bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const instance = new Temporal.Duration(1, 0, 0, 0, 24);
|
||||||
|
|
||||||
|
let relativeTo = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.total({ unit: "days", relativeTo });
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
relativeTo = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.total({ unit: "days", relativeTo });
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToRelativeTemporalObject
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
95
test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/order-of-operations.js
vendored
Normal file
95
test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/order-of-operations.js
vendored
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.plaindate.prototype.tozoneddatetime
|
||||||
|
description: User code calls happen in the correct order
|
||||||
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
const expected = [
|
||||||
|
"get item.timeZone",
|
||||||
|
"has item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has item.timeZone.getPossibleInstantsFor",
|
||||||
|
"has item.timeZone.id",
|
||||||
|
"get item.plainTime",
|
||||||
|
// ToTemporalTime
|
||||||
|
"get item.plainTime.hour",
|
||||||
|
"get item.plainTime.hour.valueOf",
|
||||||
|
"call item.plainTime.hour.valueOf",
|
||||||
|
"get item.plainTime.microsecond",
|
||||||
|
"get item.plainTime.microsecond.valueOf",
|
||||||
|
"call item.plainTime.microsecond.valueOf",
|
||||||
|
"get item.plainTime.millisecond",
|
||||||
|
"get item.plainTime.millisecond.valueOf",
|
||||||
|
"call item.plainTime.millisecond.valueOf",
|
||||||
|
"get item.plainTime.minute",
|
||||||
|
"get item.plainTime.minute.valueOf",
|
||||||
|
"call item.plainTime.minute.valueOf",
|
||||||
|
"get item.plainTime.nanosecond",
|
||||||
|
"get item.plainTime.nanosecond.valueOf",
|
||||||
|
"call item.plainTime.nanosecond.valueOf",
|
||||||
|
"get item.plainTime.second",
|
||||||
|
"get item.plainTime.second.valueOf",
|
||||||
|
"call item.plainTime.second.valueOf",
|
||||||
|
// GetInstantFor
|
||||||
|
"get item.timeZone.getPossibleInstantsFor",
|
||||||
|
"call item.timeZone.getPossibleInstantsFor",
|
||||||
|
];
|
||||||
|
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
||||||
|
const instance = new Temporal.PlainDate(2000, 1, 1, calendar);
|
||||||
|
const springForwardInstance = new Temporal.PlainDate(2000, 4, 2, calendar);
|
||||||
|
const fallBackInstance = new Temporal.PlainDate(2000, 10, 29, calendar);
|
||||||
|
actual.splice(0); // clear calendar calls that happened in constructors
|
||||||
|
|
||||||
|
const plainTime = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
hour: 2,
|
||||||
|
minute: 30,
|
||||||
|
second: 0,
|
||||||
|
millisecond: 0,
|
||||||
|
microsecond: 0,
|
||||||
|
nanosecond: 0,
|
||||||
|
}, "item.plainTime");
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const timeZone = TemporalHelpers.timeZoneObserver(actual, "item.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor,
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor,
|
||||||
|
});
|
||||||
|
const item = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
plainTime,
|
||||||
|
timeZone,
|
||||||
|
}, "item");
|
||||||
|
|
||||||
|
instance.toZonedDateTime(item);
|
||||||
|
assert.compareArray(actual, expected, "order of operations at normal wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const plainTime130 = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
hour: 1,
|
||||||
|
minute: 30,
|
||||||
|
second: 0,
|
||||||
|
millisecond: 0,
|
||||||
|
microsecond: 0,
|
||||||
|
nanosecond: 0,
|
||||||
|
}, "item.plainTime");
|
||||||
|
const item130 = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
plainTime: plainTime130,
|
||||||
|
timeZone,
|
||||||
|
}, "item");
|
||||||
|
|
||||||
|
fallBackInstance.toZonedDateTime(item130);
|
||||||
|
assert.compareArray(actual, expected, "order of operations at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
springForwardInstance.toZonedDateTime(item);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
"get item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get item.timeZone.getPossibleInstantsFor",
|
||||||
|
"call item.timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
@ -25,12 +25,38 @@ const actual = [];
|
|||||||
|
|
||||||
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
||||||
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar);
|
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar);
|
||||||
// clear observable operations that occurred during the constructor call
|
const fallBackInstance = new Temporal.PlainDateTime(2000, 10, 29, 1, 30, 0, 0, 0, 0, calendar);
|
||||||
|
const springForwardInstance = new Temporal.PlainDateTime(2000, 4, 2, 2, 30, 0, 0, 0, 0, calendar);
|
||||||
|
// clear observable operations that occurred during the constructor calls
|
||||||
actual.splice(0);
|
actual.splice(0);
|
||||||
|
|
||||||
const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone");
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor,
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor,
|
||||||
|
});
|
||||||
|
|
||||||
const options = TemporalHelpers.propertyBagObserver(actual, { disambiguation: "compatible" }, "options");
|
const options = TemporalHelpers.propertyBagObserver(actual, { disambiguation: "compatible" }, "options");
|
||||||
|
|
||||||
instance.toZonedDateTime(timeZone, options);
|
instance.toZonedDateTime(timeZone, options);
|
||||||
assert.compareArray(actual, expected, "order of operations");
|
assert.compareArray(actual, expected, "order of operations at normal wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
fallBackInstance.toZonedDateTime(timeZone, options);
|
||||||
|
assert.compareArray(actual, expected, "order of operations at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
springForwardInstance.toZonedDateTime(timeZone, options);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const rejectOptions = TemporalHelpers.propertyBagObserver(actual, { disambiguation: "reject" }, "options");
|
||||||
|
assert.throws(RangeError, () => springForwardInstance.toZonedDateTime(timeZone, rejectOptions));
|
||||||
|
assert.compareArray(actual, expected, "order of operations at skipped wall-clock time with disambiguation: reject");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
116
test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/order-of-operations.js
vendored
Normal file
116
test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/order-of-operations.js
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.plaintime.prototype.tozoneddatetime
|
||||||
|
description: User code calls happen in the correct order
|
||||||
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
const expected = [
|
||||||
|
"get item.plainDate",
|
||||||
|
"get item.plainDate.calendar",
|
||||||
|
"has item.plainDate.calendar.dateAdd",
|
||||||
|
"has item.plainDate.calendar.dateFromFields",
|
||||||
|
"has item.plainDate.calendar.dateUntil",
|
||||||
|
"has item.plainDate.calendar.day",
|
||||||
|
"has item.plainDate.calendar.dayOfWeek",
|
||||||
|
"has item.plainDate.calendar.dayOfYear",
|
||||||
|
"has item.plainDate.calendar.daysInMonth",
|
||||||
|
"has item.plainDate.calendar.daysInWeek",
|
||||||
|
"has item.plainDate.calendar.daysInYear",
|
||||||
|
"has item.plainDate.calendar.fields",
|
||||||
|
"has item.plainDate.calendar.id",
|
||||||
|
"has item.plainDate.calendar.inLeapYear",
|
||||||
|
"has item.plainDate.calendar.mergeFields",
|
||||||
|
"has item.plainDate.calendar.month",
|
||||||
|
"has item.plainDate.calendar.monthCode",
|
||||||
|
"has item.plainDate.calendar.monthDayFromFields",
|
||||||
|
"has item.plainDate.calendar.monthsInYear",
|
||||||
|
"has item.plainDate.calendar.weekOfYear",
|
||||||
|
"has item.plainDate.calendar.year",
|
||||||
|
"has item.plainDate.calendar.yearMonthFromFields",
|
||||||
|
"has item.plainDate.calendar.yearOfWeek",
|
||||||
|
"get item.plainDate.calendar.fields",
|
||||||
|
"call item.plainDate.calendar.fields",
|
||||||
|
"get item.plainDate.day",
|
||||||
|
"get item.plainDate.day.valueOf",
|
||||||
|
"call item.plainDate.day.valueOf",
|
||||||
|
"get item.plainDate.month",
|
||||||
|
"get item.plainDate.month.valueOf",
|
||||||
|
"call item.plainDate.month.valueOf",
|
||||||
|
"get item.plainDate.monthCode",
|
||||||
|
"get item.plainDate.monthCode.toString",
|
||||||
|
"call item.plainDate.monthCode.toString",
|
||||||
|
"get item.plainDate.year",
|
||||||
|
"get item.plainDate.year.valueOf",
|
||||||
|
"call item.plainDate.year.valueOf",
|
||||||
|
"get item.plainDate.calendar.dateFromFields",
|
||||||
|
"call item.plainDate.calendar.dateFromFields",
|
||||||
|
"get item.timeZone",
|
||||||
|
"has item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has item.timeZone.getPossibleInstantsFor",
|
||||||
|
"has item.timeZone.id",
|
||||||
|
"get item.timeZone.getPossibleInstantsFor",
|
||||||
|
"call item.timeZone.getPossibleInstantsFor",
|
||||||
|
];
|
||||||
|
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "item.plainDate.calendar");
|
||||||
|
const instance = new Temporal.PlainTime(2, 30);
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const timeZone = TemporalHelpers.timeZoneObserver(actual, "item.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor,
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor,
|
||||||
|
});
|
||||||
|
|
||||||
|
const plainDate = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 1,
|
||||||
|
monthCode: "M01",
|
||||||
|
day: 1,
|
||||||
|
calendar,
|
||||||
|
}, "item.plainDate");
|
||||||
|
instance.toZonedDateTime(TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
plainDate,
|
||||||
|
timeZone,
|
||||||
|
}, "item"));
|
||||||
|
assert.compareArray(actual, expected, "order of operations at normal wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const fallBackPlainDate = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 10,
|
||||||
|
monthCode: "M10",
|
||||||
|
day: 29,
|
||||||
|
calendar,
|
||||||
|
}, "item.plainDate");
|
||||||
|
const fallBackInstance = new Temporal.PlainTime(1, 30);
|
||||||
|
fallBackInstance.toZonedDateTime(TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
plainDate: fallBackPlainDate,
|
||||||
|
timeZone,
|
||||||
|
}, "item"));
|
||||||
|
assert.compareArray(actual, expected, "order of operations at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const springForwardPlainDate = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 4,
|
||||||
|
monthCode: "M04",
|
||||||
|
day: 2,
|
||||||
|
calendar,
|
||||||
|
}, "item.plainDate");
|
||||||
|
instance.toZonedDateTime(TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
plainDate: springForwardPlainDate,
|
||||||
|
timeZone,
|
||||||
|
}, "item"));
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
"get item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call item.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get item.timeZone.getPossibleInstantsFor",
|
||||||
|
"call item.timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,141 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.compare
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like property
|
||||||
|
bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const timeZone1 = TemporalHelpers.timeZoneObserver(actual, "one.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const timeZone2 = TemporalHelpers.timeZoneObserver(actual, "two.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar1 = TemporalHelpers.calendarObserver(actual, "one.calendar");
|
||||||
|
const calendar2 = TemporalHelpers.calendarObserver(actual, "two.calendar");
|
||||||
|
|
||||||
|
const expectedOne = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has one.calendar.dateAdd",
|
||||||
|
"has one.calendar.dateFromFields",
|
||||||
|
"has one.calendar.dateUntil",
|
||||||
|
"has one.calendar.day",
|
||||||
|
"has one.calendar.dayOfWeek",
|
||||||
|
"has one.calendar.dayOfYear",
|
||||||
|
"has one.calendar.daysInMonth",
|
||||||
|
"has one.calendar.daysInWeek",
|
||||||
|
"has one.calendar.daysInYear",
|
||||||
|
"has one.calendar.fields",
|
||||||
|
"has one.calendar.id",
|
||||||
|
"has one.calendar.inLeapYear",
|
||||||
|
"has one.calendar.mergeFields",
|
||||||
|
"has one.calendar.month",
|
||||||
|
"has one.calendar.monthCode",
|
||||||
|
"has one.calendar.monthDayFromFields",
|
||||||
|
"has one.calendar.monthsInYear",
|
||||||
|
"has one.calendar.weekOfYear",
|
||||||
|
"has one.calendar.year",
|
||||||
|
"has one.calendar.yearMonthFromFields",
|
||||||
|
"has one.calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get one.calendar.fields",
|
||||||
|
"call one.calendar.fields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has one.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has one.timeZone.getPossibleInstantsFor",
|
||||||
|
"has one.timeZone.id",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get one.calendar.dateFromFields",
|
||||||
|
"call one.calendar.dateFromFields",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedTwo = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has two.calendar.dateAdd",
|
||||||
|
"has two.calendar.dateFromFields",
|
||||||
|
"has two.calendar.dateUntil",
|
||||||
|
"has two.calendar.day",
|
||||||
|
"has two.calendar.dayOfWeek",
|
||||||
|
"has two.calendar.dayOfYear",
|
||||||
|
"has two.calendar.daysInMonth",
|
||||||
|
"has two.calendar.daysInWeek",
|
||||||
|
"has two.calendar.daysInYear",
|
||||||
|
"has two.calendar.fields",
|
||||||
|
"has two.calendar.id",
|
||||||
|
"has two.calendar.inLeapYear",
|
||||||
|
"has two.calendar.mergeFields",
|
||||||
|
"has two.calendar.month",
|
||||||
|
"has two.calendar.monthCode",
|
||||||
|
"has two.calendar.monthDayFromFields",
|
||||||
|
"has two.calendar.monthsInYear",
|
||||||
|
"has two.calendar.weekOfYear",
|
||||||
|
"has two.calendar.year",
|
||||||
|
"has two.calendar.yearMonthFromFields",
|
||||||
|
"has two.calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get two.calendar.fields",
|
||||||
|
"call two.calendar.fields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has two.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has two.timeZone.getPossibleInstantsFor",
|
||||||
|
"has two.timeZone.id",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get two.calendar.dateFromFields",
|
||||||
|
"call two.calendar.dateFromFields",
|
||||||
|
];
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.compare(
|
||||||
|
{ year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: timeZone1, calendar: calendar1 },
|
||||||
|
{ year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: timeZone2, calendar: calendar2 },
|
||||||
|
);
|
||||||
|
|
||||||
|
const expectedSpringForward = expectedOne.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get one.timeZone.getPossibleInstantsFor",
|
||||||
|
"call one.timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get one.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call one.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call one.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get one.timeZone.getPossibleInstantsFor",
|
||||||
|
"call one.timeZone.getPossibleInstantsFor",
|
||||||
|
], expectedTwo, [
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get two.timeZone.getPossibleInstantsFor",
|
||||||
|
"call two.timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get two.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call two.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call two.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get two.timeZone.getPossibleInstantsFor",
|
||||||
|
"call two.timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(actual, expectedSpringForward, "order of operations converting property bags at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.compare(
|
||||||
|
{ year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: timeZone1, calendar: calendar1 },
|
||||||
|
{ year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: timeZone2, calendar: calendar2 },
|
||||||
|
);
|
||||||
|
|
||||||
|
const expectedFallBack = expectedOne.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get one.timeZone.getPossibleInstantsFor",
|
||||||
|
"call one.timeZone.getPossibleInstantsFor",
|
||||||
|
], expectedTwo, [
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get two.timeZone.getPossibleInstantsFor",
|
||||||
|
"call two.timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(actual, expectedFallBack, "order of operations converting property bags at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,142 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.from
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like property
|
||||||
|
bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
];
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.from(
|
||||||
|
{ year: 2000, month: 4, day: 2, hour: 2, minute: 30, offset: "-08:00", timeZone, calendar },
|
||||||
|
{ offset: "use" }
|
||||||
|
);
|
||||||
|
assert.compareArray(actual, expected, "order of operations converting property bag at skipped wall-clock time with offset: use");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.from(
|
||||||
|
{ year: 2000, month: 4, day: 2, hour: 2, minute: 30, offset: "-08:00", timeZone, calendar },
|
||||||
|
{ offset: "ignore" }
|
||||||
|
);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations converting property bag at skipped wall-clock time with offset: ignore");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.from(
|
||||||
|
{ year: 2000, month: 4, day: 2, hour: 2, minute: 30, offset: "-08:00", timeZone, calendar },
|
||||||
|
{ offset: "prefer" }
|
||||||
|
);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations converting property bag at skipped wall-clock time with offset: prefer");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.from(
|
||||||
|
{ year: 2000, month: 10, day: 29, hour: 1, minute: 30, offset: "-08:00", timeZone, calendar },
|
||||||
|
{ offset: "use" }
|
||||||
|
);
|
||||||
|
assert.compareArray(actual, expected, "order of operations converting property bag at repeated wall-clock time with offset: use");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.from(
|
||||||
|
{ year: 2000, month: 10, day: 29, hour: 1, minute: 30, offset: "-08:00", timeZone, calendar },
|
||||||
|
{ offset: "ignore" }
|
||||||
|
);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations converting property bag at repeated wall-clock time with offset: ignore");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.from(
|
||||||
|
{ year: 2000, month: 10, day: 29, hour: 1, minute: 30, offset: "-08:00", timeZone, calendar },
|
||||||
|
{ offset: "prefer" }
|
||||||
|
);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
]), "order of operations converting property bag at repeated wall-clock time with offset: prefer");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
Temporal.ZonedDateTime.from(
|
||||||
|
{ year: 2000, month: 10, day: 29, hour: 1, minute: 30, offset: "-08:00", timeZone, calendar },
|
||||||
|
{ offset: "reject" }
|
||||||
|
);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
]), "order of operations converting property bag at repeated wall-clock time with offset: reject");
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.prototype.equals
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like property
|
||||||
|
bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const timeZone = "UTC";
|
||||||
|
const instance = new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
|
||||||
|
let arg = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.equals(arg);
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToTemporalZonedDateTime
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
arg = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.equals(arg);
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToTemporalZonedDateTime
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
109
test/built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/order-of-operations.js
vendored
Normal file
109
test/built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/order-of-operations.js
vendored
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-get-temporal.zoneddatetime.prototype.hoursinday
|
||||||
|
description: User code calls happen in the correct order
|
||||||
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
const expected = [
|
||||||
|
// GetPlainDateTimeFor
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// GetInstantFor
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// GetInstantFor
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
];
|
||||||
|
|
||||||
|
// Time zone with special requirements for testing DisambiguatePossibleInstants:
|
||||||
|
// midnight 1970-01-01 and 1970-01-02 are each in the middle of a fall-back
|
||||||
|
// transition of 1 h. Midnight 1970-01-03 and 1970-01-04 are each in the middle
|
||||||
|
// of a spring-forward transition of 1 h.
|
||||||
|
// The fall-back transitions occur 30 minutes after the day boundaries at local
|
||||||
|
// time: at epoch seconds 1800 and 91800. the spring-forward transitions occur
|
||||||
|
// 30 minutes before the day boundaries at local time: at epoch seconds 167400
|
||||||
|
// and 257400.
|
||||||
|
// This is because calculating the hours in the instance's day requires calling
|
||||||
|
// getPossibleInstantsFor on both the preceding local midnight and the following
|
||||||
|
// local midnight.
|
||||||
|
const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor(instant) {
|
||||||
|
const epochNs = instant.epochNanoseconds;
|
||||||
|
if (epochNs < 1800_000_000_000n) return 0;
|
||||||
|
if (epochNs < 91800_000_000_000n) return 3600_000_000_000;
|
||||||
|
if (epochNs < 167400_000_000_000n) return 7200_000_000_000;
|
||||||
|
if (epochNs < 257400_000_000_000n) return 3600_000_000_000;
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
getPossibleInstantsFor(dt) {
|
||||||
|
const cmp = Temporal.PlainDateTime.compare;
|
||||||
|
|
||||||
|
const zero = new Temporal.TimeZone("+00:00").getInstantFor(dt);
|
||||||
|
const one = new Temporal.TimeZone("+01:00").getInstantFor(dt);
|
||||||
|
const two = new Temporal.TimeZone("+02:00").getInstantFor(dt);
|
||||||
|
|
||||||
|
const fallBackLocalOne = new Temporal.PlainDateTime(1970, 1, 1, 0, 30);
|
||||||
|
const fallBackLocalTwo = new Temporal.PlainDateTime(1970, 1, 2, 0, 30);
|
||||||
|
const springForwardLocalOne = new Temporal.PlainDateTime(1970, 1, 2, 23, 30);
|
||||||
|
const springForwardLocalTwo = new Temporal.PlainDateTime(1970, 1, 3, 23, 30);
|
||||||
|
|
||||||
|
if (cmp(dt, fallBackLocalOne) < 0) return [zero];
|
||||||
|
if (cmp(dt, fallBackLocalOne.add({ hours: 1 })) < 0) return [zero, one];
|
||||||
|
if (cmp(dt, fallBackLocalTwo) < 0) return [one];
|
||||||
|
if (cmp(dt, fallBackLocalTwo.add({ hours: 1 })) < 0) return [one, two];
|
||||||
|
if (cmp(dt, springForwardLocalOne) < 0) return [two];
|
||||||
|
if (cmp(dt, springForwardLocalOne.add({ hours: 1 })) < 0) return [];
|
||||||
|
if (cmp(dt, springForwardLocalTwo) < 0) return [one];
|
||||||
|
if (cmp(dt, springForwardLocalTwo.add({ hours: 1 })) < 0) return [];
|
||||||
|
return [zero];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
||||||
|
|
||||||
|
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone, calendar);
|
||||||
|
const fallBackInstance = new Temporal.ZonedDateTime(43200_000_000_000n /* 1970-01-01T12:00 */, timeZone, calendar);
|
||||||
|
const springForwardInstance = new Temporal.ZonedDateTime(216000_000_000_000n /* 1970-01-03T12:00 */, timeZone, calendar);
|
||||||
|
actual.splice(0); // clear calls that happened in constructors
|
||||||
|
|
||||||
|
instance.hoursInDay;
|
||||||
|
assert.compareArray(actual, expected, "order of operations with both midnights at normal wall-clock times");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
fallBackInstance.hoursInDay;
|
||||||
|
assert.compareArray(actual, expected, "order of operations with both midnights at repeated wall-clock times");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
springForwardInstance.hoursInDay;
|
||||||
|
assert.compareArray(actual, [
|
||||||
|
// GetPlainDateTimeFor
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// GetInstantFor
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// Note, no call to dateAdd as addition takes place in the ISO calendar
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// GetInstantFor
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// Note, no call to dateAdd here either
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
], "order of operations with both midnights at skipped wall-clock times");
|
||||||
|
actual.splice(0); // clear
|
@ -41,14 +41,126 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
|
|||||||
roundingIncrement: 2,
|
roundingIncrement: 2,
|
||||||
}, "options");
|
}, "options");
|
||||||
|
|
||||||
|
const nextHourOptions = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
smallestUnit: "hour",
|
||||||
|
roundingMode: "ceil",
|
||||||
|
roundingIncrement: 1,
|
||||||
|
}, "options");
|
||||||
|
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
||||||
const instance = new Temporal.ZonedDateTime(
|
const instance = new Temporal.ZonedDateTime(
|
||||||
988786472_987_654_321n, /* 2001-05-02T06:54:32.987654321Z */
|
988786472_987_654_321n, /* 2001-05-02T06:54:32.987654321Z */
|
||||||
TemporalHelpers.timeZoneObserver(actual, "this.timeZone"),
|
TemporalHelpers.timeZoneObserver(actual, "this.timeZone"),
|
||||||
TemporalHelpers.calendarObserver(actual, "this.calendar"),
|
calendar,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fallBackTimeZone = TemporalHelpers.oneShiftTimeZone(Temporal.Instant.fromEpochSeconds(1800), -3600_000_000_000);
|
||||||
|
const fallBackTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: fallBackTimeZone.getOffsetNanosecondsFor.bind(fallBackTimeZone),
|
||||||
|
getPossibleInstantsFor: fallBackTimeZone.getPossibleInstantsFor.bind(fallBackTimeZone),
|
||||||
|
});
|
||||||
|
const fallBackInstance = new Temporal.ZonedDateTime(0n, fallBackTimeZoneObserver, calendar);
|
||||||
|
const beforeFallBackInstance = new Temporal.ZonedDateTime(-3599_000_000_000n, fallBackTimeZoneObserver, calendar);
|
||||||
|
|
||||||
|
const springForwardTimeZone = TemporalHelpers.oneShiftTimeZone(Temporal.Instant.fromEpochSeconds(-1800), 3600_000_000_000);
|
||||||
|
const springForwardTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: springForwardTimeZone.getOffsetNanosecondsFor.bind(springForwardTimeZone),
|
||||||
|
getPossibleInstantsFor: springForwardTimeZone.getPossibleInstantsFor.bind(springForwardTimeZone),
|
||||||
|
});
|
||||||
|
const springForwardInstance = new Temporal.ZonedDateTime(0n, springForwardTimeZoneObserver, calendar);
|
||||||
|
const beforeSpringForwardInstance = new Temporal.ZonedDateTime(-3599_000_000_000n, springForwardTimeZoneObserver, calendar);
|
||||||
// clear any observable operations that happen due to time zone or calendar
|
// clear any observable operations that happen due to time zone or calendar
|
||||||
// calls on the constructor
|
// calls in the constructors
|
||||||
actual.splice(0);
|
actual.splice(0);
|
||||||
|
|
||||||
instance.round(options);
|
instance.round(options);
|
||||||
assert.compareArray(actual, expected, "order of operations");
|
assert.compareArray(actual, expected, "order of operations");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
fallBackInstance.round(options);
|
||||||
|
assert.compareArray(actual, expected, "order of operations with preceding midnight at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
beforeFallBackInstance.round(nextHourOptions);
|
||||||
|
assert.compareArray(actual, expected, "order of operations with rounding result at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const expectedSkippedDateTime = [
|
||||||
|
"get options.roundingIncrement",
|
||||||
|
"get options.roundingIncrement.valueOf",
|
||||||
|
"call options.roundingIncrement.valueOf",
|
||||||
|
"get options.roundingMode",
|
||||||
|
"get options.roundingMode.toString",
|
||||||
|
"call options.roundingMode.toString",
|
||||||
|
"get options.smallestUnit",
|
||||||
|
"get options.smallestUnit.toString",
|
||||||
|
"call options.smallestUnit.toString",
|
||||||
|
// GetPlainDateTimeFor on receiver's instant
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// GetInstantFor on preceding midnight
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// AddZonedDateTime
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
];
|
||||||
|
|
||||||
|
springForwardInstance.round(options);
|
||||||
|
assert.compareArray(actual, expectedSkippedDateTime, "order of operations with preceding midnight at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const expectedSkippedResult = [
|
||||||
|
"get options.roundingIncrement",
|
||||||
|
"get options.roundingIncrement.valueOf",
|
||||||
|
"call options.roundingIncrement.valueOf",
|
||||||
|
"get options.roundingMode",
|
||||||
|
"get options.roundingMode.toString",
|
||||||
|
"call options.roundingMode.toString",
|
||||||
|
"get options.smallestUnit",
|
||||||
|
"get options.smallestUnit.toString",
|
||||||
|
"call options.smallestUnit.toString",
|
||||||
|
// GetPlainDateTimeFor on receiver's instant
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// GetInstantFor on preceding midnight
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// AddDaysToZonedDateTime
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
];
|
||||||
|
|
||||||
|
beforeSpringForwardInstance.round(nextHourOptions);
|
||||||
|
assert.compareArray(
|
||||||
|
actual,
|
||||||
|
expectedSkippedResult,
|
||||||
|
"order of operations with following midnight and rounding result at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.prototype.since
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like property
|
||||||
|
bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const timeZone = "UTC";
|
||||||
|
const instance = new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
|
||||||
|
let arg = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.since(arg);
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToTemporalZonedDateTime
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
arg = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.since(arg);
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToTemporalZonedDateTime
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
@ -269,7 +269,6 @@ assert.compareArray(actual, [
|
|||||||
"get other.timeZone.getOffsetNanosecondsFor",
|
"get other.timeZone.getOffsetNanosecondsFor",
|
||||||
"call other.timeZone.getOffsetNanosecondsFor",
|
"call other.timeZone.getOffsetNanosecondsFor",
|
||||||
// NOTE: extra because of wall-clock time ambiguity:
|
// NOTE: extra because of wall-clock time ambiguity:
|
||||||
"get other.timeZone.getOffsetNanosecondsFor",
|
|
||||||
"call other.timeZone.getOffsetNanosecondsFor",
|
"call other.timeZone.getOffsetNanosecondsFor",
|
||||||
// CalendarEquals
|
// CalendarEquals
|
||||||
"get this.calendar.id",
|
"get this.calendar.id",
|
||||||
|
67
test/built-ins/Temporal/ZonedDateTime/prototype/startOfDay/order-of-operations.js
vendored
Normal file
67
test/built-ins/Temporal/ZonedDateTime/prototype/startOfDay/order-of-operations.js
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.prototype.startofday
|
||||||
|
description: User code calls happen in the correct order
|
||||||
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetPlainDateTimeFor
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// GetInstantFor on preceding midnight
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
];
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
||||||
|
const instance = new Temporal.ZonedDateTime(
|
||||||
|
1_000_000_000_000_000_000n,
|
||||||
|
TemporalHelpers.timeZoneObserver(actual, "this.timeZone"),
|
||||||
|
calendar,
|
||||||
|
);
|
||||||
|
|
||||||
|
const fallBackTimeZone = TemporalHelpers.oneShiftTimeZone(Temporal.Instant.fromEpochSeconds(1800), -3600_000_000_000);
|
||||||
|
const fallBackInstance = new Temporal.ZonedDateTime(
|
||||||
|
0n,
|
||||||
|
TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: fallBackTimeZone.getOffsetNanosecondsFor.bind(fallBackTimeZone),
|
||||||
|
getPossibleInstantsFor: fallBackTimeZone.getPossibleInstantsFor.bind(fallBackTimeZone),
|
||||||
|
}),
|
||||||
|
calendar,
|
||||||
|
);
|
||||||
|
const springForwardTimeZone = TemporalHelpers.oneShiftTimeZone(Temporal.Instant.fromEpochSeconds(-1800), 3600_000_000_000);
|
||||||
|
const springForwardInstance = new Temporal.ZonedDateTime(
|
||||||
|
0n,
|
||||||
|
TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: springForwardTimeZone.getOffsetNanosecondsFor.bind(springForwardTimeZone),
|
||||||
|
getPossibleInstantsFor: springForwardTimeZone.getPossibleInstantsFor.bind(springForwardTimeZone),
|
||||||
|
}),
|
||||||
|
calendar,
|
||||||
|
);
|
||||||
|
// clear any observable operations that happen due to time zone or calendar
|
||||||
|
// calls in the constructors
|
||||||
|
actual.splice(0);
|
||||||
|
|
||||||
|
instance.startOfDay();
|
||||||
|
assert.compareArray(actual, expected, "order of operations");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
fallBackInstance.startOfDay();
|
||||||
|
assert.compareArray(actual, expected, "order of operations with preceding midnight at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
springForwardInstance.startOfDay();
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations with preceding midnight at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.prototype.until
|
||||||
|
description: >
|
||||||
|
Correct time zone calls are made when converting a ZonedDateTime-like property
|
||||||
|
bag denoting an ambiguous wall-clock time
|
||||||
|
includes: [temporalHelpers.js, compareArray.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor.bind(dstTimeZone),
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor.bind(dstTimeZone),
|
||||||
|
});
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar");
|
||||||
|
|
||||||
|
const timeZone = "UTC";
|
||||||
|
const instance = new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
|
||||||
|
let arg = { year: 2000, month: 4, day: 2, hour: 2, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.until(arg);
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
// GetTemporalCalendarSlotValueWithISODefault
|
||||||
|
"has calendar.dateAdd",
|
||||||
|
"has calendar.dateFromFields",
|
||||||
|
"has calendar.dateUntil",
|
||||||
|
"has calendar.day",
|
||||||
|
"has calendar.dayOfWeek",
|
||||||
|
"has calendar.dayOfYear",
|
||||||
|
"has calendar.daysInMonth",
|
||||||
|
"has calendar.daysInWeek",
|
||||||
|
"has calendar.daysInYear",
|
||||||
|
"has calendar.fields",
|
||||||
|
"has calendar.id",
|
||||||
|
"has calendar.inLeapYear",
|
||||||
|
"has calendar.mergeFields",
|
||||||
|
"has calendar.month",
|
||||||
|
"has calendar.monthCode",
|
||||||
|
"has calendar.monthDayFromFields",
|
||||||
|
"has calendar.monthsInYear",
|
||||||
|
"has calendar.weekOfYear",
|
||||||
|
"has calendar.year",
|
||||||
|
"has calendar.yearMonthFromFields",
|
||||||
|
"has calendar.yearOfWeek",
|
||||||
|
// CalendarFields
|
||||||
|
"get calendar.fields",
|
||||||
|
"call calendar.fields",
|
||||||
|
// ToTemporalTimeZoneSlotValue
|
||||||
|
"has timeZone.getOffsetNanosecondsFor",
|
||||||
|
"has timeZone.getPossibleInstantsFor",
|
||||||
|
"has timeZone.id",
|
||||||
|
// InterpretTemporalDateTimeFields
|
||||||
|
"get calendar.dateFromFields",
|
||||||
|
"call calendar.dateFromFields",
|
||||||
|
];
|
||||||
|
|
||||||
|
const expectedSpringForward = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"get timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedSpringForward.length), // ignore operations after ToTemporalZonedDateTime
|
||||||
|
expectedSpringForward,
|
||||||
|
"order of operations converting property bag at skipped wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
arg = { year: 2000, month: 10, day: 29, hour: 1, minute: 30, timeZone: dstTimeZoneObserver, calendar };
|
||||||
|
instance.until(arg);
|
||||||
|
|
||||||
|
const expectedFallBack = expected.concat([
|
||||||
|
// InterpretISODateTimeOffset
|
||||||
|
"get timeZone.getPossibleInstantsFor",
|
||||||
|
"call timeZone.getPossibleInstantsFor",
|
||||||
|
]);
|
||||||
|
assert.compareArray(
|
||||||
|
actual.slice(0, expectedFallBack.length), // ignore operations after ToTemporalZonedDateTime
|
||||||
|
expectedFallBack,
|
||||||
|
"order of operations converting property bag at repeated wall-clock time"
|
||||||
|
);
|
||||||
|
actual.splice(0); // clear
|
@ -269,7 +269,6 @@ assert.compareArray(actual, [
|
|||||||
"get other.timeZone.getOffsetNanosecondsFor",
|
"get other.timeZone.getOffsetNanosecondsFor",
|
||||||
"call other.timeZone.getOffsetNanosecondsFor",
|
"call other.timeZone.getOffsetNanosecondsFor",
|
||||||
// NOTE: extra because of wall-clock time ambiguity:
|
// NOTE: extra because of wall-clock time ambiguity:
|
||||||
"get other.timeZone.getOffsetNanosecondsFor",
|
|
||||||
"call other.timeZone.getOffsetNanosecondsFor",
|
"call other.timeZone.getOffsetNanosecondsFor",
|
||||||
// CalendarEquals
|
// CalendarEquals
|
||||||
"get this.calendar.id",
|
"get this.calendar.id",
|
||||||
|
@ -120,3 +120,55 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
|
|||||||
|
|
||||||
instance.with(fields, options);
|
instance.with(fields, options);
|
||||||
assert.compareArray(actual, expected, "order of operations");
|
assert.compareArray(actual, expected, "order of operations");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const dstTimeZoneObserver = TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor,
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor,
|
||||||
|
});
|
||||||
|
|
||||||
|
const dstInstance = new Temporal.ZonedDateTime(37800_000_000_000n /* 1970-01-01T02:30-08:00 */, dstTimeZoneObserver, calendar);
|
||||||
|
actual.splice(0); // clear calls that happened in constructor
|
||||||
|
|
||||||
|
const fallBackFields = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 10,
|
||||||
|
monthCode: "M10",
|
||||||
|
day: 29,
|
||||||
|
hour: 1,
|
||||||
|
minute: 30,
|
||||||
|
second: 0,
|
||||||
|
millisecond: 0,
|
||||||
|
microsecond: 0,
|
||||||
|
nanosecond: 0,
|
||||||
|
offset: "+00:00", // ignored
|
||||||
|
}, "fields");
|
||||||
|
dstInstance.with(fallBackFields, options);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// extra call in InterpretISODateTimeOffset
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
]), "order of operations at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const springForwardFields = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 4,
|
||||||
|
monthCode: "M04",
|
||||||
|
day: 2,
|
||||||
|
hour: 2,
|
||||||
|
minute: 30,
|
||||||
|
second: 0,
|
||||||
|
millisecond: 0,
|
||||||
|
microsecond: 0,
|
||||||
|
nanosecond: 0,
|
||||||
|
offset: "+00:00", // ignored
|
||||||
|
}, "fields");
|
||||||
|
dstInstance.with(springForwardFields, options);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
// DisambiguatePossibleInstants
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
112
test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/order-of-operations.js
vendored
Normal file
112
test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/order-of-operations.js
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-get-temporal.zoneddatetime.prototype.withplaindate
|
||||||
|
description: User code calls happen in the correct order
|
||||||
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
const expected = [
|
||||||
|
// ToTemporalDate
|
||||||
|
"get plainDateLike.calendar",
|
||||||
|
"has plainDateLike.calendar.dateAdd",
|
||||||
|
"has plainDateLike.calendar.dateFromFields",
|
||||||
|
"has plainDateLike.calendar.dateUntil",
|
||||||
|
"has plainDateLike.calendar.day",
|
||||||
|
"has plainDateLike.calendar.dayOfWeek",
|
||||||
|
"has plainDateLike.calendar.dayOfYear",
|
||||||
|
"has plainDateLike.calendar.daysInMonth",
|
||||||
|
"has plainDateLike.calendar.daysInWeek",
|
||||||
|
"has plainDateLike.calendar.daysInYear",
|
||||||
|
"has plainDateLike.calendar.fields",
|
||||||
|
"has plainDateLike.calendar.id",
|
||||||
|
"has plainDateLike.calendar.inLeapYear",
|
||||||
|
"has plainDateLike.calendar.mergeFields",
|
||||||
|
"has plainDateLike.calendar.month",
|
||||||
|
"has plainDateLike.calendar.monthCode",
|
||||||
|
"has plainDateLike.calendar.monthDayFromFields",
|
||||||
|
"has plainDateLike.calendar.monthsInYear",
|
||||||
|
"has plainDateLike.calendar.weekOfYear",
|
||||||
|
"has plainDateLike.calendar.year",
|
||||||
|
"has plainDateLike.calendar.yearMonthFromFields",
|
||||||
|
"has plainDateLike.calendar.yearOfWeek",
|
||||||
|
"get plainDateLike.calendar.fields",
|
||||||
|
"call plainDateLike.calendar.fields",
|
||||||
|
"get plainDateLike.day",
|
||||||
|
"get plainDateLike.day.valueOf",
|
||||||
|
"call plainDateLike.day.valueOf",
|
||||||
|
"get plainDateLike.month",
|
||||||
|
"get plainDateLike.month.valueOf",
|
||||||
|
"call plainDateLike.month.valueOf",
|
||||||
|
"get plainDateLike.monthCode",
|
||||||
|
"get plainDateLike.monthCode.toString",
|
||||||
|
"call plainDateLike.monthCode.toString",
|
||||||
|
"get plainDateLike.year",
|
||||||
|
"get plainDateLike.year.valueOf",
|
||||||
|
"call plainDateLike.year.valueOf",
|
||||||
|
"get plainDateLike.calendar.dateFromFields",
|
||||||
|
"call plainDateLike.calendar.dateFromFields",
|
||||||
|
// GetPlainDateTimeFor
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// ConsolidateCalendars
|
||||||
|
"get this.calendar.id",
|
||||||
|
"get plainDateLike.calendar.id",
|
||||||
|
// GetInstantFor
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
];
|
||||||
|
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
||||||
|
const plainDateCalendar = TemporalHelpers.calendarObserver(actual, "plainDateLike.calendar");
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor,
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor,
|
||||||
|
});
|
||||||
|
|
||||||
|
const instance = new Temporal.ZonedDateTime(37800_000_000_000n /* 1970-01-01T02:30-08:00 */, timeZone, calendar);
|
||||||
|
const fallBackInstance = new Temporal.ZonedDateTime(34200_000_000_000n /* 1970-01-01T01:30-08:00 */, timeZone, calendar);
|
||||||
|
actual.splice(0); // clear calls that happened in constructor
|
||||||
|
|
||||||
|
const plainDateLike = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 1,
|
||||||
|
monthCode: "M01",
|
||||||
|
day: 1,
|
||||||
|
calendar: plainDateCalendar,
|
||||||
|
}, "plainDateLike");
|
||||||
|
instance.withPlainDate(plainDateLike);
|
||||||
|
assert.compareArray(actual, expected, "order of operations at normal wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const fallBackPlainDateLike = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 10,
|
||||||
|
monthCode: "M10",
|
||||||
|
day: 29,
|
||||||
|
calendar: plainDateCalendar,
|
||||||
|
}, "plainDateLike");
|
||||||
|
fallBackInstance.withPlainDate(fallBackPlainDateLike);
|
||||||
|
assert.compareArray(actual, expected, "order of operations at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const springForwardPlainDateLike = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
year: 2000,
|
||||||
|
month: 4,
|
||||||
|
monthCode: "M04",
|
||||||
|
day: 2,
|
||||||
|
calendar: plainDateCalendar,
|
||||||
|
}, "plainDateLike");
|
||||||
|
instance.withPlainDate(springForwardPlainDateLike);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
86
test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/order-of-operations.js
vendored
Normal file
86
test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/order-of-operations.js
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-get-temporal.zoneddatetime.prototype.withplaintime
|
||||||
|
description: User code calls happen in the correct order
|
||||||
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
const expected = [
|
||||||
|
// ToTemporalTime
|
||||||
|
"get plainTimeLike.hour",
|
||||||
|
"get plainTimeLike.hour.valueOf",
|
||||||
|
"call plainTimeLike.hour.valueOf",
|
||||||
|
"get plainTimeLike.microsecond",
|
||||||
|
"get plainTimeLike.microsecond.valueOf",
|
||||||
|
"call plainTimeLike.microsecond.valueOf",
|
||||||
|
"get plainTimeLike.millisecond",
|
||||||
|
"get plainTimeLike.millisecond.valueOf",
|
||||||
|
"call plainTimeLike.millisecond.valueOf",
|
||||||
|
"get plainTimeLike.minute",
|
||||||
|
"get plainTimeLike.minute.valueOf",
|
||||||
|
"call plainTimeLike.minute.valueOf",
|
||||||
|
"get plainTimeLike.nanosecond",
|
||||||
|
"get plainTimeLike.nanosecond.valueOf",
|
||||||
|
"call plainTimeLike.nanosecond.valueOf",
|
||||||
|
"get plainTimeLike.second",
|
||||||
|
"get plainTimeLike.second.valueOf",
|
||||||
|
"call plainTimeLike.second.valueOf",
|
||||||
|
// GetPlainDateTimeFor
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
// GetInstantFor
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
];
|
||||||
|
|
||||||
|
const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
|
||||||
|
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
|
||||||
|
const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone", {
|
||||||
|
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor,
|
||||||
|
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor,
|
||||||
|
});
|
||||||
|
|
||||||
|
const instance = new Temporal.ZonedDateTime(946713600_000_000_000n /* 2000-01-01T00:00-08:00 */, timeZone, calendar);
|
||||||
|
const fallBackInstance = new Temporal.ZonedDateTime(972802800_000_000_000n /* 2000-10-29T00:00-07:00 */, timeZone, calendar);
|
||||||
|
const springForwardInstance = new Temporal.ZonedDateTime(954662400_000_000_000n /* 2000-04-02T00:00-08:00 */, timeZone, calendar);
|
||||||
|
actual.splice(0); // clear calls that happened in constructors
|
||||||
|
|
||||||
|
const plainTimeLike = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
hour: 2,
|
||||||
|
minute: 30,
|
||||||
|
second: 0,
|
||||||
|
millisecond: 0,
|
||||||
|
microsecond: 0,
|
||||||
|
nanosecond: 0,
|
||||||
|
}, "plainTimeLike");
|
||||||
|
|
||||||
|
instance.withPlainTime(plainTimeLike);
|
||||||
|
assert.compareArray(actual, expected, "order of operations at normal wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
const plainTimeLike130 = TemporalHelpers.propertyBagObserver(actual, {
|
||||||
|
hour: 1,
|
||||||
|
minute: 30,
|
||||||
|
second: 0,
|
||||||
|
millisecond: 0,
|
||||||
|
microsecond: 0,
|
||||||
|
nanosecond: 0,
|
||||||
|
}, "plainTimeLike");
|
||||||
|
|
||||||
|
fallBackInstance.withPlainTime(plainTimeLike130);
|
||||||
|
assert.compareArray(actual, expected, "order of operations at repeated wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
||||||
|
|
||||||
|
springForwardInstance.withPlainTime(plainTimeLike);
|
||||||
|
assert.compareArray(actual, expected.concat([
|
||||||
|
"get this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"call this.timeZone.getOffsetNanosecondsFor",
|
||||||
|
"get this.timeZone.getPossibleInstantsFor",
|
||||||
|
"call this.timeZone.getPossibleInstantsFor",
|
||||||
|
]), "order of operations at skipped wall-clock time");
|
||||||
|
actual.splice(0); // clear
|
Loading…
x
Reference in New Issue
Block a user