mirror of
https://github.com/tc39/test262.git
synced 2025-04-08 19:35:28 +02:00
Temporal: Add TemporalHelpers.crossDateLineTimeZone
Several tests in staging use the Pacific/Apia IANA time zone to test the behaviour of various algorithms for the case where Samoa skipped the entire day of Dec. 30, 2011, when they switched from one side of the International Date Line to the other. Since implementations are not technically required to support IANA time zones, add a fake Samoa time zone to TemporalHelpers that has the same transition, and use it in those tests. (The time zone isn't exactly the same as Pacific/Apia, since Samoa also observes DST and this time zone doesn't. It's only the same for this one transition.) See: #3649
This commit is contained in:
parent
886f091bd3
commit
46c3823117
harness
test
harness
staging/Temporal
@ -1303,6 +1303,66 @@ var TemporalHelpers = {
|
||||
return new CalendarMergeFieldsPrimitive(primitive);
|
||||
},
|
||||
|
||||
/*
|
||||
* crossDateLineTimeZone():
|
||||
*
|
||||
* This returns an instance of a custom time zone class that implements one
|
||||
* single transition where the time zone moves from one side of the
|
||||
* International Date Line to the other, for the purpose of testing time zone
|
||||
* calculations without depending on system time zone data.
|
||||
*
|
||||
* The transition occurs at epoch second 1325239200 and goes from offset
|
||||
* -10:00 to +14:00. In other words, the time zone skips the whole calendar
|
||||
* day of 2011-12-30. This is the same as the real-life transition in the
|
||||
* Pacific/Apia time zone.
|
||||
*/
|
||||
crossDateLineTimeZone() {
|
||||
const { compare } = Temporal.PlainDateTime;
|
||||
const skippedDay = new Temporal.PlainDate(2011, 12, 30);
|
||||
const transitionEpoch = 1325239200_000_000_000n;
|
||||
const beforeOffset = new Temporal.TimeZone("-10:00");
|
||||
const afterOffset = new Temporal.TimeZone("+14:00");
|
||||
|
||||
class CrossDateLineTimeZone extends Temporal.TimeZone {
|
||||
constructor() {
|
||||
super("+14:00");
|
||||
}
|
||||
|
||||
getOffsetNanosecondsFor(instant) {
|
||||
if (instant.epochNanoseconds < transitionEpoch) {
|
||||
return beforeOffset.getOffsetNanosecondsFor(instant);
|
||||
}
|
||||
return afterOffset.getOffsetNanosecondsFor(instant);
|
||||
}
|
||||
|
||||
getPossibleInstantsFor(datetime) {
|
||||
const comparison = Temporal.PlainDate.compare(datetime.toPlainDate(), skippedDay);
|
||||
if (comparison === 0) {
|
||||
return [];
|
||||
}
|
||||
if (comparison < 0) {
|
||||
return [beforeOffset.getInstantFor(datetime)];
|
||||
}
|
||||
return [afterOffset.getInstantFor(datetime)];
|
||||
}
|
||||
|
||||
getPreviousTransition(instant) {
|
||||
if (instant.epochNanoseconds > transitionEpoch) return new Temporal.Instant(transitionEpoch);
|
||||
return null;
|
||||
}
|
||||
|
||||
getNextTransition(instant) {
|
||||
if (instant.epochNanoseconds < transitionEpoch) return new Temporal.Instant(transitionEpoch);
|
||||
return null;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return "Custom/Date_Line";
|
||||
}
|
||||
}
|
||||
return new CrossDateLineTimeZone();
|
||||
},
|
||||
|
||||
/*
|
||||
* observeProperty(calls, object, propertyName, value):
|
||||
*
|
||||
|
56
test/harness/temporalHelpers-cross-date-line-time-zone.js
Normal file
56
test/harness/temporalHelpers-cross-date-line-time-zone.js
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Verify the time zone arithmetic used in
|
||||
TemporalHelpers.crossDateLineTimeZone() against the Pacific/Apia time zone in
|
||||
the implementation's time zone database
|
||||
includes: [compareArray.js, temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// No need to test this on hosts that don't provide an Intl object. It's
|
||||
// sufficient that the logic is tested on at least one host.
|
||||
if (typeof globalThis.Intl !== "undefined") {
|
||||
const tz = TemporalHelpers.crossDateLineTimeZone();
|
||||
const realTz = new Temporal.TimeZone('Pacific/Apia');
|
||||
const shiftInstant = Temporal.Instant.from('2011-12-30T10:00:00Z');
|
||||
|
||||
assert.sameValue(
|
||||
tz.getOffsetNanosecondsFor(shiftInstant),
|
||||
realTz.getOffsetNanosecondsFor(shiftInstant),
|
||||
'offset at shift instant'
|
||||
);
|
||||
const minus1 = shiftInstant.subtract({ hours: 1 });
|
||||
assert.sameValue(
|
||||
tz.getOffsetNanosecondsFor(minus1),
|
||||
realTz.getOffsetNanosecondsFor(minus1),
|
||||
'offset at 1 hour before shift'
|
||||
);
|
||||
const plus1 = shiftInstant.add({ hours: 1 });
|
||||
assert.sameValue(
|
||||
tz.getOffsetNanosecondsFor(plus1),
|
||||
realTz.getOffsetNanosecondsFor(plus1),
|
||||
'offset at 1 hour after shift'
|
||||
);
|
||||
|
||||
const middleOfSkippedDayWallTime = Temporal.PlainDateTime.from("2011-12-30T12:00");
|
||||
assert.compareArray(
|
||||
tz.getPossibleInstantsFor(middleOfSkippedDayWallTime).map((i) => i.epochNanoseconds),
|
||||
realTz.getPossibleInstantsFor(middleOfSkippedDayWallTime).map((i) => i.epochNanoseconds),
|
||||
'possible instants for middle of skipped day wall time'
|
||||
);
|
||||
const before1 = middleOfSkippedDayWallTime.subtract({ days: 1 });
|
||||
assert.compareArray(
|
||||
tz.getPossibleInstantsFor(before1).map((i) => i.epochNanoseconds),
|
||||
realTz.getPossibleInstantsFor(before1).map((i) => i.epochNanoseconds),
|
||||
'possible instants for 1 day before skipped day'
|
||||
);
|
||||
const after1 = middleOfSkippedDayWallTime.add({ days: 1 });
|
||||
assert.compareArray(
|
||||
tz.getPossibleInstantsFor(after1).map((i) => i.epochNanoseconds),
|
||||
realTz.getPossibleInstantsFor(after1).map((i) => i.epochNanoseconds),
|
||||
'possible instants for 1 day after skipped day'
|
||||
);
|
||||
}
|
@ -87,8 +87,9 @@ var relativeTo = Temporal.PlainDateTime.from("2000-10-29T12:00").toZonedDateTime
|
||||
assert.sameValue(`${ hours12.negated().add(oneDay.negated(), { relativeTo }) }`, "-P1DT11H");
|
||||
assert.sameValue(`${ oneDay.negated().add(hours12.negated(), { relativeTo }) }`, "-P1DT12H");
|
||||
|
||||
// Samoa skipped 24 hours",
|
||||
var relativeTo = Temporal.ZonedDateTime.from("2011-12-29T12:00-10:00[Pacific/Apia]");
|
||||
// Samoa skipped 24 hours
|
||||
var fakeSamoa = TemporalHelpers.crossDateLineTimeZone();
|
||||
var relativeTo = Temporal.PlainDateTime.from("2011-12-29T12:00").toZonedDateTime(fakeSamoa);
|
||||
assert.sameValue(`${ hours25.add(oneDay, { relativeTo }) }`, "P3DT1H");
|
||||
assert.sameValue(`${ oneDay.add(hours25, { relativeTo }) }`, "P3DT1H");
|
||||
|
||||
|
@ -157,8 +157,9 @@ assert.sameValue(`${ hours12.negated().round({
|
||||
relativeTo
|
||||
}) }`, "-PT12H");
|
||||
|
||||
// Samoa skipped 24 hours",
|
||||
var relativeTo = Temporal.ZonedDateTime.from("2011-12-29T12:00-10:00[Pacific/Apia]");
|
||||
// Samoa skipped 24 hours
|
||||
var fakeSamoa = TemporalHelpers.crossDateLineTimeZone();
|
||||
var relativeTo = Temporal.PlainDateTime.from("2011-12-29T12:00").toZonedDateTime(fakeSamoa);
|
||||
assert.sameValue(`${ hours25.round({
|
||||
largestUnit: "days",
|
||||
relativeTo
|
||||
|
@ -53,7 +53,8 @@ assert.sameValue(`${ twoDays.subtract(hours24, { relativeTo: repeatedHourDay })
|
||||
assert.sameValue(`${ hours24.subtract(twoDays, { relativeTo: repeatedHourDay }) }`, "-P1DT1H");
|
||||
|
||||
// Samoa skipped 24 hours
|
||||
var relativeTo = Temporal.ZonedDateTime.from("2011-12-29T12:00-10:00[Pacific/Apia]");
|
||||
var fakeSamoa = TemporalHelpers.crossDateLineTimeZone();
|
||||
var relativeTo = Temporal.PlainDateTime.from("2011-12-29T12:00").toZonedDateTime(fakeSamoa);
|
||||
assert.sameValue(`${ twoDays.subtract(Temporal.Duration.from({ hours: 48 }), { relativeTo }) }`, "-P1D");
|
||||
assert.sameValue(`${ Temporal.Duration.from({ hours: 48 }).subtract(twoDays, { relativeTo }) }`, "P2D");
|
||||
|
||||
|
@ -373,8 +373,9 @@ var totalDays = hours12.negated().total({
|
||||
});
|
||||
assert(Math.abs(totalDays - -12 / 25) < Number.EPSILON);
|
||||
|
||||
// Samoa skipped 24 hours",
|
||||
var relativeTo = Temporal.ZonedDateTime.from("2011-12-29T12:00-10:00[Pacific/Apia]");
|
||||
// Samoa skipped 24 hours
|
||||
var fakeSamoa = TemporalHelpers.crossDateLineTimeZone();
|
||||
var relativeTo = Temporal.PlainDateTime.from("2011-12-29T12:00").toZonedDateTime(fakeSamoa);
|
||||
var totalDays = hours25.total({
|
||||
unit: "days",
|
||||
relativeTo
|
||||
|
@ -44,7 +44,7 @@ var undo = added.subtract(diff);
|
||||
assert.sameValue(`${ undo }`, `${ hourBeforeDstStart }`);
|
||||
|
||||
// Samoa date line change (add): 10:00PM 29 Dec 2011 -> 11:00PM 31 Dec 2011
|
||||
var timeZone = Temporal.TimeZone.from("Pacific/Apia");
|
||||
var timeZone = TemporalHelpers.crossDateLineTimeZone();
|
||||
var dayBeforeSamoaDateLineChangeAbs = timeZone.getInstantFor(new Temporal.PlainDateTime(2011, 12, 29, 22));
|
||||
var start = dayBeforeSamoaDateLineChangeAbs.toZonedDateTimeISO(timeZone);
|
||||
var added = start.add({
|
||||
@ -60,7 +60,6 @@ var undo = added.subtract(diff);
|
||||
assert.sameValue(`${ undo }`, `${ start }`);
|
||||
|
||||
// Samoa date line change (subtract): 11:00PM 31 Dec 2011 -> 10:00PM 29 Dec 2011
|
||||
var timeZone = Temporal.TimeZone.from("Pacific/Apia");
|
||||
var dayAfterSamoaDateLineChangeAbs = timeZone.getInstantFor(new Temporal.PlainDateTime(2011, 12, 31, 23));
|
||||
var start = dayAfterSamoaDateLineChangeAbs.toZonedDateTimeISO(timeZone);
|
||||
var skipped = start.subtract({
|
||||
|
@ -27,8 +27,9 @@ var start = dayBeforeDstStart.startOfDay();
|
||||
assert.sameValue(`${ start.toPlainDate() }`, `${ dayBeforeDstStart.toPlainDate() }`);
|
||||
assert.sameValue(`${ start.toPlainTime() }`, "00:00:00");
|
||||
|
||||
var dayAfterSamoaDateLineChange = Temporal.ZonedDateTime.from("2011-12-31T22:00+14:00[Pacific/Apia]");
|
||||
var dayBeforeSamoaDateLineChange = Temporal.ZonedDateTime.from("2011-12-29T22:00-10:00[Pacific/Apia]");
|
||||
var samoa = TemporalHelpers.crossDateLineTimeZone();
|
||||
var dayAfterSamoaDateLineChange = Temporal.PlainDateTime.from("2011-12-31T22:00").toZonedDateTime(samoa);
|
||||
var dayBeforeSamoaDateLineChange = Temporal.PlainDateTime.from("2011-12-29T22:00").toZonedDateTime(samoa);
|
||||
|
||||
// startOfDay works after Samoa date line change
|
||||
var start = dayAfterSamoaDateLineChange.startOfDay();
|
||||
|
Loading…
x
Reference in New Issue
Block a user