summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/staging/Intl402
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/staging/Intl402
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/staging/Intl402')
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/browser.js0
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/addition-across-lunisolar-leap-months.js96
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/browser.js0
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/date-time-format.js1668
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/date-toLocaleString.js36
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/datetime-toLocaleString.js54
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/duration-arithmetic-dst.js76
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/hebrew-leap-months.js63
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/indian-calendar.js39
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/instant-toLocaleString.js48
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/islamic-calendars.js94
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/japanese-era.js140
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/monthday-toLocaleString.js31
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/non-iso-calendars.js1380
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/persian-calendar.js93
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/shell.js329
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/time-toLocaleString.js30
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/timezone-america-la.js31
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-string-parsing.js101
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-transitions.js47
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js42
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/old/zoneddatetime-dst-corner-cases.js29
-rw-r--r--js/src/tests/test262/staging/Intl402/Temporal/shell.js0
-rw-r--r--js/src/tests/test262/staging/Intl402/browser.js0
-rw-r--r--js/src/tests/test262/staging/Intl402/shell.js0
25 files changed, 4427 insertions, 0 deletions
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/browser.js b/js/src/tests/test262/staging/Intl402/Temporal/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/browser.js
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/addition-across-lunisolar-leap-months.js b/js/src/tests/test262/staging/Intl402/Temporal/old/addition-across-lunisolar-leap-months.js
new file mode 100644
index 0000000000..6e44e1974f
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/addition-across-lunisolar-leap-months.js
@@ -0,0 +1,96 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Addition across lunisolar leap months
+features: [Temporal]
+---*/
+
+// Adding years across Hebrew leap month
+var date = Temporal.PlainDate.from({
+ year: 5783,
+ monthCode: "M08",
+ day: 2,
+ calendar: "hebrew"
+});
+var added = date.add({ years: 1 });
+assert.sameValue(added.monthCode, date.monthCode);
+assert.sameValue(added.year, date.year + 1);
+
+// Adding months across Hebrew leap month
+var date = Temporal.PlainDate.from({
+ year: 5783,
+ monthCode: "M08",
+ day: 2,
+ calendar: "hebrew"
+});
+var added = date.add({ months: 13 });
+assert.sameValue(added.monthCode, date.monthCode);
+assert.sameValue(added.year, date.year + 1);
+
+// Adding months and years across Hebrew leap month
+var date = Temporal.PlainDate.from({
+ year: 5783,
+ monthCode: "M08",
+ day: 2,
+ calendar: "hebrew"
+});
+var added = date.add({
+ years: 1,
+ months: 12
+});
+assert.sameValue(added.monthCode, date.monthCode);
+assert.sameValue(added.year, date.year + 2);
+var testChineseData = new Date("2001-02-01T00:00Z").toLocaleString("en-US-u-ca-chinese", {
+ day: "numeric",
+ month: "numeric",
+ year: "numeric",
+ era: "short",
+ timeZone: "UTC"
+});
+var hasOutdatedChineseIcuData = !testChineseData.endsWith("2001");
+
+// Adding years across Chinese leap month"
+if(hasOutdatedChineseIcuData) {
+ var date = Temporal.PlainDate.from({
+ year: 2000,
+ monthCode: "M08",
+ day: 2,
+ calendar: "chinese"
+ });
+ var added = date.add({ years: 1 });
+ assert.sameValue(added.monthCode, date.monthCode);
+ assert.sameValue(added.year, date.year + 1);
+}
+// Adding months across Chinese leap month
+if(hasOutdatedChineseIcuData) {
+ var date = Temporal.PlainDate.from({
+ year: 2000,
+ monthCode: "M08",
+ day: 2,
+ calendar: "chinese"
+ });
+ var added = date.add({ months: 13 });
+ assert.sameValue(added.monthCode, date.monthCode);
+ assert.sameValue(added.year, date.year + 1);
+}
+
+// Adding months and years across Chinese leap month
+if(hasOutdatedChineseIcuData) {
+ var date = Temporal.PlainDate.from({
+ year: 2001,
+ monthCode: "M08",
+ day: 2,
+ calendar: "chinese"
+ });
+ var added = date.add({
+ years: 1,
+ months: 12
+ });
+ assert.sameValue(added.monthCode, date.monthCode);
+ assert.sameValue(added.year, date.year + 2);
+};
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/browser.js b/js/src/tests/test262/staging/Intl402/Temporal/old/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/browser.js
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/date-time-format.js b/js/src/tests/test262/staging/Intl402/Temporal/old/date-time-format.js
new file mode 100644
index 0000000000..2729754353
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/date-time-format.js
@@ -0,0 +1,1668 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: DateTimeFormat
+includes: [deepEqual.js]
+features: [Temporal]
+---*/
+
+// Tolerate implementation variance by expecting consistency without being prescriptive.
+// TODO: can we change tests to be less reliant on CLDR formats while still testing that
+// Temporal and Intl are behaving as expected?
+const usDayPeriodSpace =
+ new Intl.DateTimeFormat("en-US", { timeStyle: "short" })
+ .formatToParts(0)
+ .find((part, i, parts) => part.type === "literal" && parts[i + 1].type === "dayPeriod")?.value || "";
+const usDateRangeSeparator = new Intl.DateTimeFormat("en-US", { dateStyle: "short" })
+ .formatRangeToParts(1 * 86400 * 1000, 366 * 86400 * 1000)
+ .find((part) => part.type === "literal" && part.source === "shared").value;
+const deDateRangeSeparator = new Intl.DateTimeFormat("de-AT", { dateStyle: "short" })
+ .formatRangeToParts(1 * 86400 * 1000, 366 * 86400 * 1000)
+ .find((part) => part.type === "literal" && part.source === "shared").value;
+
+// Workarounds for https:// unicode-org.atlassian.net/browse/CLDR-16243
+const deMonthDayRangeSeparator = new Intl.DateTimeFormat("de-AT", { month: "numeric", day: "numeric" })
+ .formatRangeToParts(1 * 86400 * 1000, 90 * 86400 * 1000)
+ .find((part) => part.type === "literal" && part.source === "shared").value;
+const deMonthYearSeparator = new Intl.DateTimeFormat("de-AT", { year: "numeric", month: "numeric" })
+ .formatToParts(0)
+ .find((part) => part.type === "literal").value;
+const deMonthInYearMonthHasLeadingZero = new Intl.DateTimeFormat("de-AT", {
+ year: "numeric",
+ month: "numeric"
+})
+ .formatToParts(new Date(2000, 3, 1))
+ .find((part) => part.type === "month")
+ .value.startsWith("0");
+
+// should return an Array
+assert(Array.isArray(Intl.DateTimeFormat.supportedLocalesOf()));
+var onlyOnce = (value) => {
+ var obj = {
+ calls: 0,
+ toString() {
+ if (++this.calls > 1) throw new RangeError("prop read twice");
+ return value;
+ }
+ };
+ return obj;
+};
+var optionsAT = { timeZone: onlyOnce("Europe/Vienna") };
+var optionsUS = {
+ calls: 0,
+ value: "America/New_York",
+ get timeZone() {
+ if (++this.calls > 1) throw new RangeError("prop read twice");
+ return this.value;
+ },
+ set timeZone(val) {
+ this.value = val;
+ }
+};
+var localesAT = ["de-AT"];
+var us = new Intl.DateTimeFormat("en-US", optionsUS);
+var at = new Intl.DateTimeFormat(localesAT, optionsAT);
+optionsAT.timeZone = {
+ toString: () => "Bogus/Time-Zone",
+ toJSON: () => "Bogus/Time-Zone"
+};
+optionsUS.timeZone = "Bogus/Time-Zone";
+var us2 = new Intl.DateTimeFormat("en-US");
+var at2 = new Intl.DateTimeFormat(localesAT);
+localesAT[0] = ["invalid locale"];
+var usCalendar = us.resolvedOptions().calendar;
+var atCalendar = at.resolvedOptions().calendar;
+var t1 = "1976-11-18T14:23:30+00:00[UTC]";
+var t2 = "2020-02-20T15:44:56-05:00[America/New_York]";
+var start = new Date("1922-12-30");
+var end = new Date("1991-12-26");
+
+// should work for Instant
+assert.sameValue(us.format(Temporal.Instant.from(t1)), `11/18/1976, 9:23:30${usDayPeriodSpace}AM`);
+assert.sameValue(at.format(Temporal.Instant.from(t1)), "18.11.1976, 15:23:30");
+
+// should work for DateTime
+assert.sameValue(us.format(Temporal.PlainDateTime.from(t1)), `11/18/1976, 2:23:30${usDayPeriodSpace}PM`);
+assert.sameValue(at.format(Temporal.PlainDateTime.from(t1)), "18.11.1976, 14:23:30");
+
+// should work for Time
+assert.sameValue(us.format(Temporal.PlainTime.from(t1)), `2:23:30${usDayPeriodSpace}PM`);
+assert.sameValue(at.format(Temporal.PlainTime.from(t1)), "14:23:30");
+
+// should work for Date
+assert.sameValue(us.format(Temporal.PlainDate.from(t1)), "11/18/1976");
+assert.sameValue(at.format(Temporal.PlainDate.from(t1)), "18.11.1976");
+
+// should work for YearMonth
+var t = Temporal.PlainDate.from(t1);
+assert.sameValue(us.format(t.withCalendar(usCalendar).toPlainYearMonth()), "11/1976");
+assert.sameValue(at.format(t.withCalendar(atCalendar).toPlainYearMonth()), `11${deMonthYearSeparator}1976`);
+
+// should work for MonthDay
+var t = Temporal.PlainDate.from(t1);
+assert.sameValue(us.format(t.withCalendar(usCalendar).toPlainMonthDay()), "11/18");
+assert.sameValue(at.format(t.withCalendar(atCalendar).toPlainMonthDay()), "18.11.");
+
+// should not break legacy Date
+assert.sameValue(us.format(start), "12/29/1922");
+assert.sameValue(at.format(start), "30.12.1922");
+
+// should work for Instant
+assert.deepEqual(us.formatToParts(Temporal.Instant.from(t2)), [
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "day",
+ value: "20"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "year",
+ value: "2020"
+ },
+ {
+ type: "literal",
+ value: ", "
+ },
+ {
+ type: "hour",
+ value: "3"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "minute",
+ value: "44"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "second",
+ value: "56"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace
+ },
+ {
+ type: "dayPeriod",
+ value: "PM"
+ }
+]);
+assert.deepEqual(at.formatToParts(Temporal.Instant.from(t2)), [
+ {
+ type: "day",
+ value: "20"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "year",
+ value: "2020"
+ },
+ {
+ type: "literal",
+ value: ", "
+ },
+ {
+ type: "hour",
+ value: "21"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "minute",
+ value: "44"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "second",
+ value: "56"
+ }
+]);
+// should work for DateTime
+assert.deepEqual(us.formatToParts(Temporal.PlainDateTime.from(t2)), [
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "day",
+ value: "20"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "year",
+ value: "2020"
+ },
+ {
+ type: "literal",
+ value: ", "
+ },
+ {
+ type: "hour",
+ value: "3"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "minute",
+ value: "44"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "second",
+ value: "56"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace
+ },
+ {
+ type: "dayPeriod",
+ value: "PM"
+ }
+]);
+assert.deepEqual(at.formatToParts(Temporal.PlainDateTime.from(t2)), [
+ {
+ type: "day",
+ value: "20"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "year",
+ value: "2020"
+ },
+ {
+ type: "literal",
+ value: ", "
+ },
+ {
+ type: "hour",
+ value: "15"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "minute",
+ value: "44"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "second",
+ value: "56"
+ }
+]);
+// should work for Time
+assert.deepEqual(us.formatToParts(Temporal.PlainTime.from(t2)), [
+ {
+ type: "hour",
+ value: "3"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "minute",
+ value: "44"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "second",
+ value: "56"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace
+ },
+ {
+ type: "dayPeriod",
+ value: "PM"
+ }
+]);
+assert.deepEqual(at.formatToParts(Temporal.PlainTime.from(t2)), [
+ {
+ type: "hour",
+ value: "15"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "minute",
+ value: "44"
+ },
+ {
+ type: "literal",
+ value: ":"
+ },
+ {
+ type: "second",
+ value: "56"
+ }
+]);
+// should work for Date
+assert.deepEqual(us.formatToParts(Temporal.PlainDate.from(t2)), [
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "day",
+ value: "20"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "year",
+ value: "2020"
+ }
+]);
+assert.deepEqual(at.formatToParts(Temporal.PlainDate.from(t2)), [
+ {
+ type: "day",
+ value: "20"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "year",
+ value: "2020"
+ }
+]);
+// should work for YearMonth
+var t = Temporal.PlainDate.from(t2);
+assert.deepEqual(us.formatToParts(t.withCalendar(usCalendar).toPlainYearMonth()), [
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "year",
+ value: "2020"
+ }
+]);
+assert.deepEqual(at.formatToParts(t.withCalendar(atCalendar).toPlainYearMonth()), [
+ {
+ type: "month",
+ value: deMonthInYearMonthHasLeadingZero ? "02" : "2"
+ },
+ {
+ type: "literal",
+ value: deMonthYearSeparator
+ },
+ {
+ type: "year",
+ value: "2020"
+ }
+]);
+// should work for MonthDay
+var t = Temporal.PlainDate.from(t2);
+assert.deepEqual(us.formatToParts(t.withCalendar(usCalendar).toPlainMonthDay()), [
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "day",
+ value: "20"
+ }
+]);
+assert.deepEqual(at.formatToParts(t.withCalendar(atCalendar).toPlainMonthDay()), [
+ {
+ type: "day",
+ value: "20"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "month",
+ value: "2"
+ },
+ {
+ type: "literal",
+ value: "."
+ }
+]);
+// should not break legacy Date
+assert.deepEqual(us.formatToParts(end), [
+ {
+ type: "month",
+ value: "12"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "day",
+ value: "25"
+ },
+ {
+ type: "literal",
+ value: "/"
+ },
+ {
+ type: "year",
+ value: "1991"
+ }
+]);
+assert.deepEqual(at.formatToParts(end), [
+ {
+ type: "day",
+ value: "26"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "month",
+ value: "12"
+ },
+ {
+ type: "literal",
+ value: "."
+ },
+ {
+ type: "year",
+ value: "1991"
+ }
+]);
+// formatRange
+// should work for Instant
+assert.sameValue(
+ us.formatRange(Temporal.Instant.from(t1), Temporal.Instant.from(t2)),
+ `11/18/1976, 9:23:30${usDayPeriodSpace}AM${usDateRangeSeparator}2/20/2020, 3:44:56${usDayPeriodSpace}PM`
+);
+assert.sameValue(
+ at.formatRange(Temporal.Instant.from(t1), Temporal.Instant.from(t2)),
+ `18.11.1976, 15:23:30${deDateRangeSeparator}20.2.2020, 21:44:56`
+);
+
+// should work for DateTime
+assert.sameValue(
+ us.formatRange(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2)),
+ `11/18/1976, 2:23:30${usDayPeriodSpace}PM${usDateRangeSeparator}2/20/2020, 3:44:56${usDayPeriodSpace}PM`
+);
+assert.sameValue(
+ at.formatRange(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2)),
+ `18.11.1976, 14:23:30${deDateRangeSeparator}20.2.2020, 15:44:56`
+);
+
+// should work for Time
+assert.sameValue(
+ us.formatRange(Temporal.PlainTime.from(t1), Temporal.PlainTime.from(t2)),
+ `2:23:30${usDayPeriodSpace}PM${usDateRangeSeparator}3:44:56${usDayPeriodSpace}PM`
+);
+assert.sameValue(
+ at.formatRange(Temporal.PlainTime.from(t1), Temporal.PlainTime.from(t2)),
+ `14:23:30${deDateRangeSeparator}15:44:56`
+);
+
+// should work for Date
+assert.sameValue(
+ us.formatRange(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2)),
+ `11/18/1976${usDateRangeSeparator}2/20/2020`
+);
+assert.sameValue(
+ at.formatRange(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2)),
+ `18.11.1976${deDateRangeSeparator}20.02.2020`
+);
+
+// should work for YearMonth
+var date1 = Temporal.PlainDate.from(t1);
+var date2 = Temporal.PlainDate.from(t2);
+assert.sameValue(
+ us.formatRange(date1.withCalendar(usCalendar).toPlainYearMonth(), date2.withCalendar(usCalendar).toPlainYearMonth()),
+ `11/1976${usDateRangeSeparator}2/2020`
+);
+assert.sameValue(
+ at.formatRange(date1.withCalendar(atCalendar).toPlainYearMonth(), date2.withCalendar(atCalendar).toPlainYearMonth()),
+ `11${deMonthYearSeparator}1976${deDateRangeSeparator}02${deMonthYearSeparator}2020`
+);
+
+// should work for MonthDay
+var date1 = Temporal.PlainDate.from(t1);
+var date2 = Temporal.PlainDate.from(t2);
+assert.sameValue(
+ us.formatRange(date2.withCalendar(usCalendar).toPlainMonthDay(), date1.withCalendar(usCalendar).toPlainMonthDay()),
+ `2/20${usDateRangeSeparator}11/18`
+);
+assert.sameValue(
+ at.formatRange(date2.withCalendar(atCalendar).toPlainMonthDay(), date1.withCalendar(atCalendar).toPlainMonthDay()),
+ `20.02${deMonthDayRangeSeparator}18.11.`
+);
+
+// should not break legacy Date
+assert.sameValue(us.formatRange(start, end), `12/29/1922${usDateRangeSeparator}12/25/1991`);
+assert.sameValue(at.formatRange(start, end), `30.12.1922${deDateRangeSeparator}26.12.1991`);
+
+// should throw a RangeError when called with different calendars
+assert.throws(RangeError, () =>
+ us.formatRange(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2).withCalendar("japanese"))
+);
+assert.throws(RangeError, () =>
+ us.formatRange(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2).withCalendar("japanese"))
+);
+
+// formatRangeToParts
+// should work for Instant
+assert.deepEqual(us.formatRangeToParts(Temporal.Instant.from(t1), Temporal.Instant.from(t2)), [
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "day",
+ value: "18",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "startRange"
+ },
+ {
+ type: "hour",
+ value: "9",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "minute",
+ value: "23",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "second",
+ value: "30",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace,
+ source: "startRange"
+ },
+ {
+ type: "dayPeriod",
+ value: "AM",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "month",
+ value: "2",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "day",
+ value: "20",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "endRange"
+ },
+ {
+ type: "hour",
+ value: "3",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "minute",
+ value: "44",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "second",
+ value: "56",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace,
+ source: "endRange"
+ },
+ {
+ type: "dayPeriod",
+ value: "PM",
+ source: "endRange"
+ }
+]);
+assert.deepEqual(at.formatRangeToParts(Temporal.Instant.from(t1), Temporal.Instant.from(t2)), [
+ {
+ type: "day",
+ value: "18",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "startRange"
+ },
+ {
+ type: "hour",
+ value: "15",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "minute",
+ value: "23",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "second",
+ value: "30",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "day",
+ value: "20",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "month",
+ value: "2",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "endRange"
+ },
+ {
+ type: "hour",
+ value: "21",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "minute",
+ value: "44",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "second",
+ value: "56",
+ source: "endRange"
+ }
+]);
+// should work for DateTime
+assert.deepEqual(us.formatRangeToParts(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2)), [
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "day",
+ value: "18",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "startRange"
+ },
+ {
+ type: "hour",
+ value: "2",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "minute",
+ value: "23",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "second",
+ value: "30",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace,
+ source: "startRange"
+ },
+ {
+ type: "dayPeriod",
+ value: "PM",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "month",
+ value: "2",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "day",
+ value: "20",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "endRange"
+ },
+ {
+ type: "hour",
+ value: "3",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "minute",
+ value: "44",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "second",
+ value: "56",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace,
+ source: "endRange"
+ },
+ {
+ type: "dayPeriod",
+ value: "PM",
+ source: "endRange"
+ }
+]);
+assert.deepEqual(at.formatRangeToParts(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2)), [
+ {
+ type: "day",
+ value: "18",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "startRange"
+ },
+ {
+ type: "hour",
+ value: "14",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "minute",
+ value: "23",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "second",
+ value: "30",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "day",
+ value: "20",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "month",
+ value: "2",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ", ",
+ source: "endRange"
+ },
+ {
+ type: "hour",
+ value: "15",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "minute",
+ value: "44",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "second",
+ value: "56",
+ source: "endRange"
+ }
+]);
+// should work for Time
+assert.deepEqual(us.formatRangeToParts(Temporal.PlainTime.from(t1), Temporal.PlainTime.from(t2)), [
+ {
+ type: "hour",
+ value: "2",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "minute",
+ value: "23",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "second",
+ value: "30",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace,
+ source: "startRange"
+ },
+ {
+ type: "dayPeriod",
+ value: "PM",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "hour",
+ value: "3",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "minute",
+ value: "44",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "second",
+ value: "56",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: usDayPeriodSpace,
+ source: "endRange"
+ },
+ {
+ type: "dayPeriod",
+ value: "PM",
+ source: "endRange"
+ }
+]);
+assert.deepEqual(at.formatRangeToParts(Temporal.PlainTime.from(t1), Temporal.PlainTime.from(t2)), [
+ {
+ type: "hour",
+ value: "14",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "minute",
+ value: "23",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "startRange"
+ },
+ {
+ type: "second",
+ value: "30",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "hour",
+ value: "15",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "minute",
+ value: "44",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ":",
+ source: "endRange"
+ },
+ {
+ type: "second",
+ value: "56",
+ source: "endRange"
+ }
+]);
+// should work for Date
+assert.deepEqual(us.formatRangeToParts(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2)), [
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "day",
+ value: "18",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "month",
+ value: "2",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "day",
+ value: "20",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ }
+]);
+assert.deepEqual(at.formatRangeToParts(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2)), [
+ {
+ type: "day",
+ value: "18",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "day",
+ value: "20",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "month",
+ value: "02",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ }
+]);
+// should work for YearMonth
+var date1 = Temporal.PlainDate.from(t1);
+var date2 = Temporal.PlainDate.from(t2);
+assert.deepEqual(
+ us.formatRangeToParts(
+ date1.withCalendar(usCalendar).toPlainYearMonth(),
+ date2.withCalendar(usCalendar).toPlainYearMonth()
+ ),
+ [
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "month",
+ value: "2",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ }
+ ]
+);
+assert.deepEqual(
+ at.formatRangeToParts(
+ date1.withCalendar(atCalendar).toPlainYearMonth(),
+ date2.withCalendar(atCalendar).toPlainYearMonth()
+ ),
+ [
+ {
+ type: "month",
+ value: "11",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deMonthYearSeparator,
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1976",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "month",
+ value: "02",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: deMonthYearSeparator,
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "2020",
+ source: "endRange"
+ }
+ ]
+);
+// should work for MonthDay
+var date1 = Temporal.PlainDate.from(t1);
+var date2 = Temporal.PlainDate.from(t2);
+assert.deepEqual(
+ us.formatRangeToParts(
+ date2.withCalendar(usCalendar).toPlainMonthDay(),
+ date1.withCalendar(usCalendar).toPlainMonthDay()
+ ),
+ [
+ {
+ type: "month",
+ value: "2",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "day",
+ value: "20",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "month",
+ value: "11",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "day",
+ value: "18",
+ source: "endRange"
+ }
+ ]
+);
+assert.deepEqual(
+ at.formatRangeToParts(
+ date2.withCalendar(atCalendar).toPlainMonthDay(),
+ date1.withCalendar(atCalendar).toPlainMonthDay()
+ ),
+ [
+ {
+ type: "day",
+ value: "20",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "month",
+ value: "02",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deMonthDayRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "day",
+ value: "18",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "month",
+ value: "11",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "shared"
+ }
+ ]
+);
+// should not break legacy Date
+assert.deepEqual(us.formatRangeToParts(start, end), [
+ {
+ type: "month",
+ value: "12",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "day",
+ value: "29",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1922",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: usDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "month",
+ value: "12",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "day",
+ value: "25",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: "/",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "1991",
+ source: "endRange"
+ }
+]);
+assert.deepEqual(at.formatRangeToParts(start, end), [
+ {
+ type: "day",
+ value: "30",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "month",
+ value: "12",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "startRange"
+ },
+ {
+ type: "year",
+ value: "1922",
+ source: "startRange"
+ },
+ {
+ type: "literal",
+ value: deDateRangeSeparator,
+ source: "shared"
+ },
+ {
+ type: "day",
+ value: "26",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "month",
+ value: "12",
+ source: "endRange"
+ },
+ {
+ type: "literal",
+ value: ".",
+ source: "endRange"
+ },
+ {
+ type: "year",
+ value: "1991",
+ source: "endRange"
+ }
+]);
+// should throw a TypeError when called with dissimilar types
+assert.throws(TypeError, () => at.formatRangeToParts(Temporal.Instant.from(t1), Temporal.PlainDateTime.from(t2)));
+// should throw a RangeError when called with different calendars
+assert.throws(RangeError, () =>
+ at.formatRangeToParts(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2).withCalendar("japanese"))
+);
+assert.throws(RangeError, () =>
+ at.formatRangeToParts(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2).withCalendar("japanese"))
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/date-toLocaleString.js b/js/src/tests/test262/staging/Intl402/Temporal/old/date-toLocaleString.js
new file mode 100644
index 0000000000..973705f4ac
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/date-toLocaleString.js
@@ -0,0 +1,36 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: date.toLocaleString()
+features: [Temporal]
+---*/
+
+function maybeGetWeekdayOnlyFormat() {
+ const fmt = new Intl.DateTimeFormat('en', { weekday: 'long', timeZone: 'Europe/Vienna' });
+ if (
+ ['era', 'year', 'month', 'day', 'hour', 'minute', 'second', 'timeZoneName'].some(
+ (prop) => prop in fmt.resolvedOptions()
+ )
+ ) {
+ //no weekday-only format available
+ return null;
+ }
+ return fmt;
+}
+
+var date = Temporal.PlainDate.from("1976-11-18T15:23:30");
+assert.sameValue(`${ date.toLocaleString("en-US", { timeZone: "America/New_York" }) }`, "11/18/1976");
+assert.sameValue(`${ date.toLocaleString("de-AT", { timeZone: "Europe/Vienna" }) }`, "18.11.1976");
+var fmt = maybeGetWeekdayOnlyFormat();
+if (fmt) assert.sameValue(fmt.format(date), "Thursday");
+
+// should ignore units not in the data type
+assert.sameValue(date.toLocaleString("en-US", { timeZoneName: "long" }), "11/18/1976");
+assert.sameValue(date.toLocaleString("en-US", { hour: "numeric" }), "11/18/1976");
+assert.sameValue(date.toLocaleString("en-US", { minute: "numeric" }), "11/18/1976");
+assert.sameValue(date.toLocaleString("en-US", { second: "numeric" }), "11/18/1976");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/datetime-toLocaleString.js b/js/src/tests/test262/staging/Intl402/Temporal/old/datetime-toLocaleString.js
new file mode 100644
index 0000000000..3cdced3faa
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/datetime-toLocaleString.js
@@ -0,0 +1,54 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: datetime.toLocaleString()
+features: [Temporal]
+---*/
+
+// Tolerate implementation variance by expecting consistency without being prescriptive.
+// TODO: can we change tests to be less reliant on CLDR formats while still testing that
+// Temporal and Intl are behaving as expected?
+const usDayPeriodSpace =
+ new Intl.DateTimeFormat("en-US", { timeStyle: "short" })
+ .formatToParts(0)
+ .find((part, i, parts) => part.type === "literal" && parts[i + 1].type === "dayPeriod")?.value || "";
+
+function maybeGetWeekdayOnlyFormat() {
+ const fmt = new Intl.DateTimeFormat("en-US", { weekday: "long", timeZone: "Europe/Vienna" });
+ if (
+ ["era", "year", "month", "day", "hour", "minute", "second", "timeZoneName"].some(
+ (prop) => prop in fmt.resolvedOptions()
+ )
+ ) {
+ // no weekday-only format available
+ return null;
+ }
+ return fmt;
+}
+
+var datetime = Temporal.PlainDateTime.from("1976-11-18T15:23:30");
+assert.sameValue(
+ `${datetime.toLocaleString("en-US", { timeZone: "America/New_York" })}`,
+ `11/18/1976, 3:23:30${usDayPeriodSpace}PM`
+);
+assert.sameValue(`${datetime.toLocaleString("de-AT", { timeZone: "Europe/Vienna" })}`, "18.11.1976, 15:23:30");
+var fmt = maybeGetWeekdayOnlyFormat();
+if (fmt) assert.sameValue(fmt.format(datetime), "Thursday");
+
+// should ignore units not in the data type
+assert.sameValue(
+ datetime.toLocaleString("en-US", { timeZoneName: "long" }),
+ `11/18/1976, 3:23:30${usDayPeriodSpace}PM`
+);
+
+// should use compatible disambiguation option
+var dstStart = new Temporal.PlainDateTime(2020, 3, 8, 2, 30);
+assert.sameValue(
+ `${dstStart.toLocaleString("en-US", { timeZone: "America/Los_Angeles" })}`,
+ `3/8/2020, 3:30:00${usDayPeriodSpace}AM`
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/duration-arithmetic-dst.js b/js/src/tests/test262/staging/Intl402/Temporal/old/duration-arithmetic-dst.js
new file mode 100644
index 0000000000..08e9c8b428
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/duration-arithmetic-dst.js
@@ -0,0 +1,76 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-duration-objects
+description: >
+ Various DST arithmetic tests that it's impractical to do without a time zone
+ database in the implementation
+features: [Temporal]
+---*/
+
+// Tests for arithmetic that start inside a repeated hour, and end in a skipped
+// hour. We have TemporalHelpers.springForwardFallBackTimeZone which is
+// sufficient to test this for Temporal.Duration.prototype.add, and
+// Temporal.Duration.prototype.round, but it's impractical to replicate all the
+// TZDB data for testing it with other methods such as subtract() where we need
+// to calculate to the _next_ transition
+
+var skippedHourDay = Temporal.ZonedDateTime.from("2019-03-10T00:00[America/Vancouver]");
+var repeatedHourDay = Temporal.ZonedDateTime.from("2019-11-03T00:00[America/Vancouver]");
+var inRepeatedHour = Temporal.ZonedDateTime.from("2019-11-03T01:00-07:00[America/Vancouver]");
+
+// subtract()
+
+var oneDay = new Temporal.Duration(0, 0, 0, 1);
+assert.sameValue(`${ Temporal.Duration.from({
+ days: 127,
+ hours: 1
+}).subtract(oneDay, { relativeTo: inRepeatedHour }) }`, "P126DT1H");
+var hours24 = new Temporal.Duration(0, 0, 0, 0, 24);
+assert.sameValue(`${ Temporal.Duration.from({
+ days: 127,
+ hours: 1
+}).subtract(hours24, { relativeTo: inRepeatedHour }) }`, "P126D");
+
+// total()
+var totalDays = Temporal.Duration.from({
+ days: 126,
+ hours: 1
+}).total({
+ unit: "days",
+ relativeTo: inRepeatedHour
+});
+assert(Math.abs(totalDays - (126 + 1 / 23)) < Number.EPSILON);
+assert.sameValue(Temporal.Duration.from({
+ days: 126,
+ hours: 1
+}).total({
+ unit: "hours",
+ relativeTo: inRepeatedHour
+}), 3026);
+
+// Tests for casting relativeTo to ZonedDateTime when possible:
+// Without a TZDB, it's not possible to get a ZonedDateTime with DST from a
+// string.
+
+assert.sameValue(
+ `${ oneDay.add(hours24, { relativeTo: "2019-11-02T00:00[America/Vancouver]" }) }`,
+ "P1DT24H"
+);
+var hours25 = new Temporal.Duration(0, 0, 0, 0, 25);
+assert.sameValue(`${ hours25.round({
+ largestUnit: "days",
+ relativeTo: "2019-11-03T00:00[America/Vancouver]"
+}) }`, "P1D");
+assert.sameValue(
+ `${ oneDay.subtract(hours24, { relativeTo: "2019-11-03T00:00[America/Vancouver]" }) }`,
+ "PT1H"
+);
+assert.sameValue(oneDay.total({
+ unit: "hours",
+ relativeTo: "2019-11-03T00:00[America/Vancouver]"
+}), 25);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/hebrew-leap-months.js b/js/src/tests/test262/staging/Intl402/Temporal/old/hebrew-leap-months.js
new file mode 100644
index 0000000000..bdd410c4cf
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/hebrew-leap-months.js
@@ -0,0 +1,63 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Hebrew leap months
+features: [Temporal]
+---*/
+
+// Valid leap month: Adar I 5779
+var date = Temporal.PlainDate.from({
+ year: 5779,
+ month: 6,
+ day: 1,
+ calendar: "hebrew"
+});
+assert.sameValue(date.month, 6);
+assert.sameValue(date.monthCode, "M05L");
+assert.sameValue(date.day, 1);
+date = Temporal.PlainDate.from({
+ year: 5779,
+ monthCode: "M05L",
+ day: 1,
+ calendar: "hebrew"
+});
+assert.sameValue(date.month, 6);
+assert.sameValue(date.monthCode, "M05L");
+assert.sameValue(date.day, 1);
+
+// Creating dates in later months in a leap year
+var date = Temporal.PlainDate.from({
+ year: 5779,
+ month: 7,
+ day: 1,
+ calendar: "hebrew"
+});
+assert.sameValue(date.month, 7);
+assert.sameValue(date.monthCode, "M06");
+assert.sameValue(date.day, 1);
+date = Temporal.PlainDate.from({
+ year: 5779,
+ monthCode: "M06",
+ day: 1,
+ calendar: "hebrew"
+});
+assert.sameValue(date.month, 7);
+assert.sameValue(date.monthCode, "M06");
+assert.sameValue(date.day, 1);
+
+// Invalid leap months: e.g. M02L
+for (var i = 1; i <= 12; i++) {
+ if (i === 5)
+ continue;
+ assert.throws(RangeError, () => Temporal.PlainDate.from({
+ year: 5779,
+ monthCode: `M${ i.toString().padStart(2, "0") }L`,
+ day: 1,
+ calendar: "hebrew"
+ }));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/indian-calendar.js b/js/src/tests/test262/staging/Intl402/Temporal/old/indian-calendar.js
new file mode 100644
index 0000000000..1e82b4bc3f
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/indian-calendar.js
@@ -0,0 +1,39 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Indian calendar
+features: [Temporal]
+---*/
+
+
+// throws in Node 12 & 14 before 1 CE
+var vulnerableToBceBug = new Date("0000-01-01T00:00Z").toLocaleDateString("en-US-u-ca-indian", { timeZone: "UTC" }) !== "10/11/-79 Saka";
+if (vulnerableToBceBug) {
+ assert.throws(RangeError, () => Temporal.PlainDate.from("0000-01-01").withCalendar("indian").day);
+}
+
+// handles leap days
+var leapYearFirstDay = Temporal.PlainDate.from("2004-03-21[u-ca=indian]");
+assert.sameValue(leapYearFirstDay.year, 2004 - 78);
+assert.sameValue(leapYearFirstDay.month, 1);
+assert.sameValue(leapYearFirstDay.day, 1);
+var leapYearLastDay = leapYearFirstDay.with({ day: 31 });
+assert.sameValue(leapYearLastDay.year, 2004 - 78);
+assert.sameValue(leapYearLastDay.month, 1);
+assert.sameValue(leapYearLastDay.day, 31);
+
+// handles non-leap years
+var nonLeapYearFirstDay = Temporal.PlainDate.from("2005-03-22[u-ca=indian]");
+assert.sameValue(nonLeapYearFirstDay.year, 2005 - 78);
+assert.sameValue(nonLeapYearFirstDay.month, 1);
+assert.sameValue(nonLeapYearFirstDay.day, 1);
+var leapYearLastDay = nonLeapYearFirstDay.with({ day: 31 });
+assert.sameValue(leapYearLastDay.year, 2005 - 78);
+assert.sameValue(leapYearLastDay.month, 1);
+assert.sameValue(leapYearLastDay.day, 30);
+assert.throws(RangeError, () => nonLeapYearFirstDay.with({ day: 31 }, { overflow: "reject" }));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/instant-toLocaleString.js b/js/src/tests/test262/staging/Intl402/Temporal/old/instant-toLocaleString.js
new file mode 100644
index 0000000000..5854d0dcdf
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/instant-toLocaleString.js
@@ -0,0 +1,48 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Instant.toLocaleString()
+features: [Temporal]
+---*/
+
+// Tolerate implementation variance by expecting consistency without being prescriptive.
+// TODO: can we change tests to be less reliant on CLDR formats while still testing that
+// Temporal and Intl are behaving as expected?
+const usDayPeriodSpace =
+ new Intl.DateTimeFormat("en-US", { timeStyle: "short" })
+ .formatToParts(0)
+ .find((part, i, parts) => part.type === "literal" && parts[i + 1].type === "dayPeriod")?.value || "";
+
+function maybeGetWeekdayOnlyFormat() {
+ const fmt = new Intl.DateTimeFormat("en-US", { weekday: "long", timeZone: "Europe/Vienna" });
+ if (
+ ["era", "year", "month", "day", "hour", "minute", "second", "timeZoneName"].some(
+ (prop) => prop in fmt.resolvedOptions()
+ )
+ ) {
+ // no weekday-only format available
+ return null;
+ }
+ return fmt;
+}
+
+var instant = Temporal.Instant.from("1976-11-18T14:23:30Z");
+assert.sameValue(
+ `${instant.toLocaleString("en-US", { timeZone: "America/New_York" })}`,
+ `11/18/1976, 9:23:30${usDayPeriodSpace}AM`
+);
+assert.sameValue(`${instant.toLocaleString("de-AT", { timeZone: "Europe/Vienna" })}`, "18.11.1976, 15:23:30");
+var fmt = maybeGetWeekdayOnlyFormat();
+if (fmt) assert.sameValue(fmt.format(instant), "Thursday");
+
+// outputs timeZoneName if requested
+var str = instant.toLocaleString("en-US", {
+ timeZone: "America/New_York",
+ timeZoneName: "short"
+});
+assert(str.includes("EST"));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/islamic-calendars.js b/js/src/tests/test262/staging/Intl402/Temporal/old/islamic-calendars.js
new file mode 100644
index 0000000000..c0726b0cae
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/islamic-calendars.js
@@ -0,0 +1,94 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2023 Justin Grant. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Islamic calendars (note there are 6 variants)
+features: [Temporal]
+---*/
+
+// Test data obtained from ICU
+
+const tests = [
+ {
+ calendar: "islamic",
+ inLeapYear: false,
+ daysInYear: 354,
+ daysInMonth12: 29,
+ isoYear: 2023,
+ isoMonth: 7,
+ isoDay: 18
+ },
+ {
+ calendar: "islamic-umalqura",
+ inLeapYear: false,
+ daysInYear: 354,
+ daysInMonth12: 30,
+ isoYear: 2023,
+ isoMonth: 7,
+ isoDay: 19
+ },
+ {
+ calendar: "islamic-civil",
+ inLeapYear: true,
+ daysInYear: 355,
+ daysInMonth12: 30,
+ isoYear: 2023,
+ isoMonth: 7,
+ isoDay: 19
+ },
+ {
+ calendar: "islamicc", // deprecated version of islamic-civil
+ inLeapYear: true,
+ daysInYear: 355,
+ daysInMonth12: 30,
+ isoYear: 2023,
+ isoMonth: 7,
+ isoDay: 19
+ },
+ {
+ calendar: "islamic-rgsa",
+ inLeapYear: false,
+ daysInYear: 354,
+ daysInMonth12: 29,
+ isoYear: 2023,
+ isoMonth: 7,
+ isoDay: 18
+ },
+ {
+ calendar: "islamic-tbla",
+ inLeapYear: true,
+ daysInYear: 355,
+ daysInMonth12: 30,
+ isoYear: 2023,
+ isoMonth: 7,
+ isoDay: 18
+ }
+];
+
+for (const test of tests) {
+ const { calendar, inLeapYear, daysInYear, daysInMonth12, isoYear, isoMonth, isoDay } = test;
+ const year = 1445;
+ const date = Temporal.PlainDate.from({ year, month: 1, day: 1, calendar });
+ const isoFields = date.getISOFields();
+ assert.sameValue(date.calendarId, calendar);
+ assert.sameValue(date.year, year);
+ assert.sameValue(date.month, 1);
+ assert.sameValue(date.monthCode, "M01");
+ assert.sameValue(date.day, 1);
+ assert.sameValue(date.inLeapYear, inLeapYear);
+ assert.sameValue(date.daysInYear, daysInYear);
+ assert.sameValue(date.monthsInYear, 12);
+ assert.sameValue(date.dayOfYear, 1);
+ const startOfNextYear = date.with({ year: year + 1 });
+ const lastDayOfThisYear = startOfNextYear.subtract({ days: 1 });
+ assert.sameValue(lastDayOfThisYear.dayOfYear, daysInYear);
+ const dateMonth12 = date.with({ month: 12 });
+ assert.sameValue(dateMonth12.daysInMonth, daysInMonth12);
+ assert.sameValue(isoYear, isoFields.isoYear);
+ assert.sameValue(isoMonth, isoFields.isoMonth);
+ assert.sameValue(isoDay, isoFields.isoDay);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/japanese-era.js b/js/src/tests/test262/staging/Intl402/Temporal/old/japanese-era.js
new file mode 100644
index 0000000000..47e16fbcb5
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/japanese-era.js
@@ -0,0 +1,140 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Japanese eras
+features: [Temporal]
+---*/
+
+
+// Reiwa (2019-)
+var date = Temporal.PlainDate.from({
+ era: "reiwa",
+ eraYear: 2,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "2020-01-01[u-ca=japanese]");
+
+// Heisei (1989-2019)
+var date = Temporal.PlainDate.from({
+ era: "heisei",
+ eraYear: 2,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1990-01-01[u-ca=japanese]");
+
+// Showa (1926-1989)
+var date = Temporal.PlainDate.from({
+ era: "showa",
+ eraYear: 2,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1927-01-01[u-ca=japanese]");
+
+// Taisho (1912-1926)
+var date = Temporal.PlainDate.from({
+ era: "taisho",
+ eraYear: 2,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1913-01-01[u-ca=japanese]");
+
+// Meiji (1868-1912)
+var date = Temporal.PlainDate.from({
+ era: "meiji",
+ eraYear: 2,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1869-01-01[u-ca=japanese]");
+
+// Dates in same year before Japanese era starts will resolve to previous era
+var date = Temporal.PlainDate.from({
+ era: "reiwa",
+ eraYear: 1,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "2019-01-01[u-ca=japanese]");
+assert.sameValue(date.era, "heisei");
+assert.sameValue(date.eraYear, 31);
+
+date = Temporal.PlainDate.from({
+ era: "heisei",
+ eraYear: 1,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1989-01-01[u-ca=japanese]");
+assert.sameValue(date.era, "showa");
+assert.sameValue(date.eraYear, 64);
+date = Temporal.PlainDate.from({
+ era: "showa",
+ eraYear: 1,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1926-01-01[u-ca=japanese]");
+assert.sameValue(date.era, "taisho");
+assert.sameValue(date.eraYear, 15);
+
+date = Temporal.PlainDate.from({
+ era: "taisho",
+ eraYear: 1,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1912-01-01[u-ca=japanese]");
+assert.sameValue(date.era, "meiji");
+assert.sameValue(date.eraYear, 45);
+
+date = Temporal.PlainDate.from({
+ era: "meiji",
+ eraYear: 1,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${ date }`, "1868-01-01[u-ca=japanese]");
+assert.sameValue(date.era, "ce");
+assert.sameValue(date.eraYear, 1868);
+
+// Verify that CE and BCE eras (before Meiji) are recognized
+date = Temporal.PlainDate.from({
+ era: "ce",
+ eraYear: 1000,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${date}`, "1000-01-01[u-ca=japanese]");
+assert.sameValue(date.era, "ce");
+assert.sameValue(date.eraYear, 1000);
+
+date = Temporal.PlainDate.from({
+ era: "bce",
+ eraYear: 1,
+ month: 1,
+ day: 1,
+ calendar: "japanese"
+});
+assert.sameValue(`${date}`, "0000-01-01[u-ca=japanese]");
+assert.sameValue(date.era, "bce");
+assert.sameValue(date.eraYear, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/monthday-toLocaleString.js b/js/src/tests/test262/staging/Intl402/Temporal/old/monthday-toLocaleString.js
new file mode 100644
index 0000000000..a0452c1ab1
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/monthday-toLocaleString.js
@@ -0,0 +1,31 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: monthday.toLocaleString()
+features: [Temporal]
+---*/
+
+var calendar = new Intl.DateTimeFormat("en-US").resolvedOptions().calendar;
+var monthday = Temporal.PlainMonthDay.from({
+ monthCode: "M11",
+ day: 18,
+ calendar
+});
+assert.sameValue(`${ monthday.toLocaleString("en-US", { timeZone: "America/New_York" }) }`, "11/18");
+assert.sameValue(`${ monthday.toLocaleString("de-AT", {
+ timeZone: "Europe/Vienna",
+ calendar
+}) }`, "18.11.");
+
+// should ignore units not in the data type
+assert.sameValue(monthday.toLocaleString("en-US", { timeZoneName: "long" }), "11/18");
+assert.sameValue(monthday.toLocaleString("en-US", { year: "numeric" }), "11/18");
+assert.sameValue(monthday.toLocaleString("en-US", { hour: "numeric" }), "11/18");
+assert.sameValue(monthday.toLocaleString("en-US", { minute: "numeric" }), "11/18");
+assert.sameValue(monthday.toLocaleString("en-US", { second: "numeric" }), "11/18");
+assert.sameValue(monthday.toLocaleString("en-US", { weekday: "long" }), "11/18");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/non-iso-calendars.js b/js/src/tests/test262/staging/Intl402/Temporal/old/non-iso-calendars.js
new file mode 100644
index 0000000000..a4f1a2908f
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/non-iso-calendars.js
@@ -0,0 +1,1380 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Non-ISO Calendars
+features: [Temporal, Array.prototype.includes]
+---*/
+
+var testChineseData = new Date("2001-02-01T00:00Z").toLocaleString("en-US-u-ca-chinese", {
+ day: "numeric",
+ month: "numeric",
+ year: "numeric",
+ era: "short",
+ timeZone: "UTC"
+});
+var hasOutdatedChineseIcuData = !testChineseData.endsWith("2001");
+
+// verify that Intl.DateTimeFormat.formatToParts output matches snapshot data
+var getLocalizedDates = isoString => {
+ var calendars = [
+ "iso8601",
+ "buddhist",
+ "chinese",
+ "coptic",
+ "dangi",
+ "ethioaa",
+ "ethiopic",
+ "gregory",
+ "hebrew",
+ "indian",
+ "islamic",
+ "islamic-umalqura",
+ "islamic-tbla",
+ "islamic-civil",
+ "islamic-rgsa",
+ "islamicc",
+ "japanese",
+ "persian",
+ "roc"
+ ];
+ var date = new Date(isoString);
+ return calendars.map(id => `${ id }: ${ date.toLocaleDateString(`en-US-u-ca-${ id }`, { timeZone: "UTC" }) }`).join("\n");
+};
+var year2000Content = getLocalizedDates("2000-01-01T00:00Z");
+var year1Content = getLocalizedDates("0001-01-01T00:00Z");
+var year2000Snapshot = "iso8601: 1/1/2000\n" + "buddhist: 1/1/2543 BE\n" + "chinese: 11/25/1999\n" + "coptic: 4/22/1716 ERA1\n" + "dangi: 11/25/1999\n" + "ethioaa: 4/22/7492 ERA0\n" + "ethiopic: 4/22/1992 ERA1\n" + "gregory: 1/1/2000\n" + "hebrew: 23 Tevet 5760\n" + "indian: 10/11/1921 Saka\n" + "islamic: 9/25/1420 AH\n" + "islamic-umalqura: 9/24/1420 AH\n" + "islamic-tbla: 9/25/1420 AH\n" + "islamic-civil: 9/24/1420 AH\n" + "islamic-rgsa: 9/25/1420 AH\n" + "islamicc: 9/24/1420 AH\n" + "japanese: 1/1/12 H\n" + "persian: 10/11/1378 AP\n" + "roc: 1/1/89 Minguo";
+assert.sameValue(year2000Content, year2000Snapshot);
+
+// Several calendars based on the Gregorian calendar use Julian dates (not
+// proleptic Gregorian dates) before the Gregorian switchover in Oct 1582. See
+// https://bugs.chromium.org/p/chromium/issues/detail?id=1173158. The code below
+// allows these tests to pass regardless of the bug, while still remaining
+// sensitive to other bugs that may crop up.
+const yearOneMonthDay = new Map(
+ ["iso8601", "gregory", "roc", "buddhist", "japanese"].map(calendar => {
+ hasGregorianSwitchoverBug = new Date("+001001-01-01T00:00Z")
+ .toLocaleDateString(`en-US-u-ca-${calendar}`, { timeZone: "UTC" })
+ .startsWith("12");
+ return [calendar, hasGregorianSwitchoverBug ? "1/3" : "1/1"]
+ }));
+var year1Snapshot =
+ `iso8601: ${yearOneMonthDay.get("iso8601")}/1\n` +
+ `buddhist: ${yearOneMonthDay.get("buddhist")}/544 BE\n` +
+ "chinese: 11/21/0\n" +
+ "coptic: 5/8/284 ERA0\n" +
+ "dangi: 11/21/0\n" +
+ "ethioaa: 5/8/5493 ERA0\n" +
+ "ethiopic: 5/8/5493 ERA0\n" +
+ `gregory: ${yearOneMonthDay.get("gregory")}/1\n` +
+ "hebrew: 18 Tevet 3761\n" +
+ "indian: 10/11/-78 Saka\n" +
+ "islamic: 5/20/-640 AH\n" +
+ "islamic-umalqura: 5/18/-640 AH\n" +
+ "islamic-tbla: 5/19/-640 AH\n" +
+ "islamic-civil: 5/18/-640 AH\n" +
+ "islamic-rgsa: 5/20/-640 AH\n" +
+ "islamicc: 5/18/-640 AH\n" +
+ `japanese: ${yearOneMonthDay.get("japanese")}/-643 Taika (645\u2013650)\n` +
+ "persian: 10/11/-621 AP\n" +
+ `roc: ${yearOneMonthDay.get("roc")}/1911 B.R.O.C.`;
+assert.sameValue(year1Content, year1Snapshot);
+var fromWithCases = {
+ iso8601: {
+ year2000: {
+ year: 2000,
+ month: 1,
+ day: 1
+ },
+ year1: {
+ year: 1,
+ month: 1,
+ day: 1
+ }
+ },
+ buddhist: {
+ year2000: {
+ year: 2543,
+ month: 1,
+ day: 1,
+ era: "be"
+ },
+ year1: RangeError
+ },
+ chinese: {
+ year2000: {
+ year: 1999,
+ month: 11,
+ day: 25
+ },
+ year1: {
+ year: 0,
+ month: 12,
+ monthCode: "M11",
+ day: 21
+ }
+ },
+ coptic: {
+ year2000: {
+ year: 1716,
+ month: 4,
+ day: 22,
+ era: "era1"
+ },
+ year1: {
+ year: -283,
+ eraYear: 284,
+ month: 5,
+ day: 8,
+ era: "era0"
+ }
+ },
+ dangi: {
+ year2000: {
+ year: 1999,
+ month: 11,
+ day: 25
+ },
+ year1: {
+ year: 0,
+ month: 12,
+ monthCode: "M11",
+ day: 21
+ }
+ },
+ ethioaa: {
+ year2000: {
+ year: 7492,
+ month: 4,
+ day: 22,
+ era: "era0"
+ },
+ year1: {
+ year: 5493,
+ month: 5,
+ day: 8,
+ era: "era0"
+ }
+ },
+ ethiopic: {
+ year2000: {
+ eraYear: 1992,
+ year: 7492,
+ month: 4,
+ day: 22,
+ era: "era1"
+ },
+ year1: {
+ year: 5493,
+ month: 5,
+ day: 8,
+ era: "era0"
+ }
+ },
+ gregory: {
+ year2000: {
+ year: 2000,
+ month: 1,
+ day: 1,
+ era: "ce"
+ },
+ year1: {
+ year: 1,
+ month: 1,
+ day: 1,
+ era: "ce"
+ }
+ },
+ hebrew: {
+ year2000: {
+ year: 5760,
+ month: 4,
+ day: 23
+ },
+ year1: {
+ year: 3761,
+ month: 4,
+ day: 18
+ }
+ },
+ indian: {
+ year2000: {
+ year: 1921,
+ month: 10,
+ day: 11,
+ era: "saka"
+ },
+ year1: {
+ year: -78,
+ month: 10,
+ day: 11,
+ era: "saka"
+ }
+ },
+ islamic: {
+ year2000: {
+ year: 1420,
+ month: 9,
+ day: 25,
+ era: "ah"
+ },
+ year1: {
+ year: -640,
+ month: 5,
+ day: 20,
+ era: "ah"
+ }
+ },
+ "islamic-umalqura": {
+ year2000: {
+ year: 1420,
+ month: 9,
+ day: 24,
+ era: "ah"
+ },
+ year1: {
+ year: -640,
+ month: 5,
+ day: 18,
+ era: "ah"
+ }
+ },
+ "islamic-tbla": {
+ year2000: {
+ year: 1420,
+ month: 9,
+ day: 25,
+ era: "ah"
+ },
+ year1: {
+ year: -640,
+ month: 5,
+ day: 19,
+ era: "ah"
+ }
+ },
+ "islamic-civil": {
+ year2000: {
+ year: 1420,
+ month: 9,
+ day: 24,
+ era: "ah"
+ },
+ year1: {
+ year: -640,
+ month: 5,
+ day: 18,
+ era: "ah"
+ }
+ },
+ "islamic-rgsa": {
+ year2000: {
+ year: 1420,
+ month: 9,
+ day: 25,
+ era: "ah"
+ },
+ year1: {
+ year: -640,
+ month: 5,
+ day: 20,
+ era: "ah"
+ }
+ },
+ islamicc: {
+ year2000: {
+ year: 1420,
+ month: 9,
+ day: 24,
+ era: "ah"
+ },
+ year1: {
+ year: -640,
+ month: 5,
+ day: 18,
+ era: "ah"
+ }
+ },
+ japanese: {
+ year2000: {
+ year: 2000,
+ eraYear: 12,
+ month: 1,
+ day: 1,
+ era: "heisei"
+ },
+ year1: RangeError
+ },
+ persian: {
+ year2000: {
+ year: 1378,
+ month: 10,
+ day: 11,
+ era: "ap"
+ },
+ year1: {
+ year: -621,
+ month: 10,
+ day: 11,
+ era: "ap"
+ }
+ },
+ roc: {
+ year2000: {
+ year: 89,
+ month: 1,
+ day: 1,
+ era: "minguo"
+ },
+ year1: RangeError
+ }
+};
+var logPerf = false;
+var totalNow = 0;
+for (var [id, tests] of Object.entries(fromWithCases)) {
+ var dates = {
+ year2000: Temporal.PlainDate.from("2000-01-01"),
+ year1: Temporal.PlainDate.from("0001-01-01")
+ };
+ for (var [name, date] of Object.entries(dates)) {
+ var values = tests[name];
+ var errorExpected = values === RangeError;
+ if ((id === "chinese" || id === "dangi") && hasOutdatedChineseIcuData ) {
+ var now = globalThis.performance ? globalThis.performance.now() : Date.now();
+ if (errorExpected) {
+ assert.throws(RangeError, () => {
+ var inCal = date.withCalendar(id);
+ Temporal.PlainDate.from({
+ calendar: id,
+ year: inCal.year,
+ day: inCal.day,
+ monthCode: inCal.monthCode
+ });
+ });
+ }
+ var inCal = date.withCalendar(id);
+ assert.sameValue(`${ name } ${ id } day: ${ inCal.day }`, `${ name } ${ id } day: ${ values.day }`);
+ if (values.eraYear === undefined && values.era !== undefined)
+ values.eraYear = values.year;
+ assert.sameValue(`${ name } ${ id } eraYear: ${ inCal.eraYear }`, `${ name } ${ id } eraYear: ${ values.eraYear }`);
+ assert.sameValue(`${ name } ${ id } era: ${ inCal.era }`, `${ name } ${ id } era: ${ values.era }`);
+ assert.sameValue(`${ name } ${ id } year: ${ inCal.year }`, `${ name } ${ id } year: ${ values.year }`);
+ assert.sameValue(`${ name } ${ id } month: ${ inCal.month }`, `${ name } ${ id } month: ${ values.month }`);
+ if (values.monthCode === undefined)
+ values.monthCode = `M${ values.month.toString().padStart(2, "0") }`;
+ assert.sameValue(`${ name } ${ id } monthCode: ${ inCal.monthCode }`, `${ name } ${ id } monthCode: ${ values.monthCode }`);
+ if (values.era) {
+ var dateRoundtrip1 = Temporal.PlainDate.from({
+ calendar: id,
+ eraYear: values.eraYear,
+ era: values.era,
+ day: values.day,
+ monthCode: values.monthCode
+ });
+ assert.sameValue(dateRoundtrip1.toString(), inCal.toString());
+ assert.throws(RangeError, () => Temporal.PlainDate.from({
+ calendar: id,
+ eraYear: values.eraYear,
+ era: values.era,
+ day: values.day,
+ monthCode: values.monthCode,
+ year: values.year + 1
+ }));
+ }
+ var dateRoundtrip2 = Temporal.PlainDate.from({
+ calendar: id,
+ year: values.year,
+ day: values.day,
+ monthCode: values.monthCode
+ });
+ assert.sameValue(dateRoundtrip2.toString(), inCal.toString());
+ var dateRoundtrip3 = Temporal.PlainDate.from({
+ calendar: id,
+ year: values.year,
+ day: values.day,
+ month: values.month
+ });
+ assert.sameValue(dateRoundtrip3.toString(), inCal.toString());
+ var dateRoundtrip4 = Temporal.PlainDate.from({
+ calendar: id,
+ year: values.year,
+ day: values.day,
+ monthCode: values.monthCode
+ });
+ assert.sameValue(dateRoundtrip4.toString(), inCal.toString());
+ assert.throws(RangeError, () => Temporal.PlainDate.from({
+ calendar: id,
+ day: values.day,
+ month: values.month === 1 ? 2 : values.month - 1,
+ monthCode: values.monthCode,
+ year: values.year
+ }));
+ var ms = (globalThis.performance ? globalThis.performance.now() : Date.now()) - now;
+ totalNow += ms;
+ if (logPerf)
+ console.log(`from: ${ id } ${ name }: ${ ms.toFixed(2) }ms, total: ${ totalNow.toFixed(2) }ms`);
+ };
+ if ((id === "chinese" || id === "dangi") && hasOutdatedChineseIcuData ) {
+ var now = globalThis.performance ? globalThis.performance.now() : Date.now();
+ var inCal = date.withCalendar(id);
+ if (errorExpected) {
+ assert.throws(RangeError, () => inCal.with({ day: 1 }).year);
+ }
+ var afterWithDay = inCal.with({ day: 1 });
+ var t = "(after setting day)";
+ assert.sameValue(`${ t } year: ${ afterWithDay.year }`, `${ t } year: ${ inCal.year }`);
+ assert.sameValue(`${ t } month: ${ afterWithDay.month }`, `${ t } month: ${ inCal.month }`);
+ assert.sameValue(`${ t } day: ${ afterWithDay.day }`, `${ t } day: 1`);
+ var afterWithMonth = afterWithDay.with({ month: 1 });
+ t = "(after setting month)";
+ assert.sameValue(`${ t } year: ${ afterWithMonth.year }`, `${ t } year: ${ inCal.year }`);
+ assert.sameValue(`${ t } month: ${ afterWithMonth.month }`, `${ t } month: 1`);
+ assert.sameValue(`${ t } day: ${ afterWithMonth.day }`, `${ t } day: 1`);
+ var afterWithYear = afterWithMonth.with({ year: 2220 });
+ t = "(after setting year)";
+ assert.sameValue(`${ t } year: ${ afterWithYear.year }`, `${ t } year: 2220`);
+ assert.sameValue(`${ t } month: ${ afterWithYear.month }`, `${ t } month: 1`);
+ assert.sameValue(`${ t } day: ${ afterWithYear.day }`, `${ t } day: 1`);
+ var ms = (globalThis.performance ? globalThis.performance.now() : Date.now()) - now;
+ totalNow += ms;
+ if (logPerf)
+ console.log(`with: ${ id } ${ name }: ${ ms.toFixed(2) }ms, total: ${ totalNow.toFixed(2) }ms`);
+ };
+ }
+}
+var addDaysWeeksCases = {
+ iso8601: {
+ year: 2000,
+ month: 10,
+ day: 7,
+ monthCode: "M10",
+ eraYear: undefined,
+ era: undefined
+ },
+ buddhist: RangeError,
+ chinese: {
+ year: 2000,
+ month: 10,
+ day: 16,
+ monthCode: "M10",
+ eraYear: undefined,
+ era: undefined
+ },
+ coptic: {
+ year: 2000,
+ month: 10,
+ day: 11,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "era1"
+ },
+ dangi: {
+ year: 2000,
+ month: 10,
+ day: 16,
+ monthCode: "M10",
+ eraYear: undefined,
+ era: undefined
+ },
+ ethioaa: {
+ year: 2000,
+ month: 10,
+ day: 11,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "era0"
+ },
+ ethiopic: {
+ year: 2000,
+ month: 10,
+ day: 11,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "era0"
+ },
+ gregory: {
+ year: 2000,
+ month: 10,
+ day: 7,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ce"
+ },
+ hebrew: {
+ year: 2000,
+ month: 10,
+ day: 14,
+ monthCode: "M10",
+ eraYear: undefined,
+ era: undefined
+ },
+ indian: {
+ year: 2000,
+ month: 10,
+ day: 6,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "saka"
+ },
+ islamic: {
+ year: 2000,
+ month: 10,
+ day: 15,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ah"
+ },
+ "islamic-umalqura": {
+ year: 2000,
+ month: 10,
+ day: 15,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ah"
+ },
+ "islamic-tbla": {
+ year: 2000,
+ month: 10,
+ day: 15,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ah"
+ },
+ "islamic-civil": {
+ year: 2000,
+ month: 10,
+ day: 15,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ah"
+ },
+ "islamic-rgsa": {
+ year: 2000,
+ month: 10,
+ day: 15,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ah"
+ },
+ islamicc: {
+ year: 2000,
+ month: 10,
+ day: 15,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ah"
+ },
+ japanese: {
+ year: 2000,
+ month: 10,
+ day: 7,
+ monthCode: "M10",
+ eraYear: 12,
+ era: "heisei"
+ },
+ persian: {
+ year: 2000,
+ month: 10,
+ day: 5,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "ap"
+ },
+ roc: {
+ year: 2000,
+ month: 10,
+ day: 8,
+ monthCode: "M10",
+ eraYear: 2000,
+ era: "minguo"
+ }
+};
+const addMonthsCases = {
+ iso8601: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: undefined, era: undefined },
+ // See https://bugs.chromium.org/p/chromium/issues/detail?id=1173158
+ buddhist: RangeError, // { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'be' },
+ chinese: { year: 2001, month: 6, day: 1, monthCode: 'M05', eraYear: undefined, era: undefined },
+ coptic: { year: 2001, month: 5, day: 1, monthCode: 'M05', eraYear: 2001, era: 'era1' },
+ dangi: { year: 2001, month: 6, day: 1, monthCode: 'M05', eraYear: undefined, era: undefined },
+ ethioaa: { year: 2001, month: 5, day: 1, monthCode: 'M05', eraYear: 2001, era: 'era0' },
+ ethiopic: { year: 2001, month: 5, day: 1, monthCode: 'M05', eraYear: 2001, era: 'era0' },
+ gregory: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ce' },
+ hebrew: { year: 2001, month: 6, day: 1, monthCode: 'M05L', eraYear: undefined, era: undefined },
+ indian: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'saka' },
+ islamic: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ah' },
+ 'islamic-umalqura': { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ah' },
+ 'islamic-tbla': { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ah' },
+ 'islamic-civil': { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ah' },
+ 'islamic-rgsa': { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ah' },
+ islamicc: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ah' },
+ japanese: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 13, era: 'heisei' },
+ persian: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'ap' },
+ roc: { year: 2001, month: 6, day: 1, monthCode: 'M06', eraYear: 2001, era: 'minguo' }
+};
+var i = 0;
+const addYearsMonthsDaysCases = Object.entries(addMonthsCases).reduce((obj, entry) => {
+ obj[entry[0]] = entry[1] === RangeError ? RangeError : { ...entry[1], day: 18 };
+ return obj;
+}, {});
+var tests = {
+ days: {
+ duration: { days: 280 },
+ results: addDaysWeeksCases,
+ startDate: {
+ year: 2000,
+ month: 1,
+ day: 1
+ }
+ },
+ weeks: {
+ duration: { weeks: 40 },
+ results: addDaysWeeksCases,
+ startDate: {
+ year: 2000,
+ month: 1,
+ day: 1
+ }
+ },
+ months: {
+ duration: { months: 6 },
+ results: addMonthsCases,
+ startDate: {
+ year: 2000,
+ month: 12,
+ day: 1
+ }
+ },
+ years: {
+ duration: {
+ years: 3,
+ months: 6,
+ days: 17
+ },
+ results: addYearsMonthsDaysCases,
+ startDate: {
+ year: 1997,
+ monthCode: "M12",
+ day: 1
+ }
+ }
+};
+var calendars = Object.keys(addMonthsCases);
+for (var id of calendars) {
+ for (var [unit, {duration, results, startDate}] of Object.entries(tests)) {
+ var values = results[id];
+ duration = Temporal.Duration.from(duration);
+ if ((id === "chinese" || id === "dangi") && hasOutdatedChineseIcuData ) {
+ var now = globalThis.performance ? globalThis.performance.now() : Date.now();
+ if (values === RangeError) {
+ assert.throws(RangeError, () => Temporal.PlainDate.from({
+ ...startDate,
+ calendar: id
+ }));
+ }
+ var start = Temporal.PlainDate.from({
+ ...startDate,
+ calendar: id
+ });
+ var end = start.add(duration);
+ assert.sameValue(`add ${ unit } ${ id } day: ${ end.day }`, `add ${ unit } ${ id } day: ${ values.day }`);
+ assert.sameValue(`add ${ unit } ${ id } eraYear: ${ end.eraYear }`, `add ${ unit } ${ id } eraYear: ${ values.eraYear }`);
+ assert.sameValue(`add ${ unit } ${ id } era: ${ end.era }`, `add ${ unit } ${ id } era: ${ values.era }`);
+ assert.sameValue(`add ${ unit } ${ id } year: ${ end.year }`, `add ${ unit } ${ id } year: ${ values.year }`);
+ assert.sameValue(`add ${ unit } ${ id } month: ${ end.month }`, `add ${ unit } ${ id } month: ${ values.month }`);
+ assert.sameValue(`add ${ unit } ${ id } monthCode: ${ end.monthCode }`, `add ${ unit } ${ id } monthCode: ${ values.monthCode }`);
+ var calculatedStart = end.subtract(duration);
+ var isLunisolar = [
+ "chinese",
+ "dangi",
+ "hebrew"
+ ].includes(id);
+ var expectedCalculatedStart = isLunisolar && duration.years !== 0 && !end.monthCode.endsWith("L") ? start.subtract({ months: 1 }) : start;
+ assert.sameValue(`start ${ calculatedStart.toString() }`, `start ${ expectedCalculatedStart.toString() }`);
+ var diff = start.until(end, { largestUnit: unit });
+ assert.sameValue(`diff ${ unit } ${ id }: ${ diff }`, `diff ${ unit } ${ id }: ${ duration }`);
+ if (unit === "months") {
+ var startYesterday = start.subtract({ days: 1 });
+ var endYesterday = startYesterday.add(duration);
+ assert.sameValue(`add from end-of-month ${ unit } ${ id } day (initial): ${ endYesterday.day }`, `add from end-of-month ${ unit } ${ id } day (initial): ${ Math.min(startYesterday.day, endYesterday.daysInMonth) }`);
+ var endYesterdayNextDay = endYesterday.add({ days: 1 });
+ while (endYesterdayNextDay.day !== 1) {
+ endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 });
+ }
+ assert.sameValue(`add from end-of-month ${ unit } ${ id } day: ${ endYesterdayNextDay.day }`, `add from end-of-month ${ unit } ${ id } day: ${ values.day }`);
+ assert.sameValue(`add from end-of-month ${ unit } ${ id } eraYear: ${ endYesterdayNextDay.eraYear }`, `add from end-of-month ${ unit } ${ id } eraYear: ${ values.eraYear }`);
+ assert.sameValue(`add from end-of-month ${ unit } ${ id } era: ${ endYesterdayNextDay.era }`, `add from end-of-month ${ unit } ${ id } era: ${ values.era }`);
+ assert.sameValue(`add from end-of-month ${ unit } ${ id } year: ${ endYesterdayNextDay.year }`, `add from end-of-month ${ unit } ${ id } year: ${ values.year }`);
+ assert.sameValue(`add from end-of-month ${ unit } ${ id } month: ${ endYesterdayNextDay.month }`, `add from end-of-month ${ unit } ${ id } month: ${ values.month }`);
+ assert.sameValue(`add from end-of-month ${ unit } ${ id } monthCode: ${ endYesterdayNextDay.monthCode }`, `add from end-of-month ${ unit } ${ id } monthCode: ${ values.monthCode }`);
+ var endReverse = endYesterdayNextDay.subtract({ days: 1 });
+ var startReverse = endReverse.subtract(duration);
+ assert.sameValue(`subtract from end-of-month ${ unit } ${ id } day (initial): ${ startReverse.day }`, `subtract from end-of-month ${ unit } ${ id } day (initial): ${ Math.min(endReverse.day, startReverse.daysInMonth) }`);
+ var startReverseNextDay = startReverse.add({ days: 1 });
+ while (startReverseNextDay.day !== 1) {
+ startReverseNextDay = startReverseNextDay.add({ days: 1 });
+ }
+ assert.sameValue(`subtract from end-of-month ${ unit } ${ id } day: ${ startReverseNextDay.day }`, `subtract from end-of-month ${ unit } ${ id } day: ${ start.day }`);
+ assert.sameValue(`subtract from end-of-month ${ unit } ${ id } eraYear: ${ startReverseNextDay.eraYear }`, `subtract from end-of-month ${ unit } ${ id } eraYear: ${ start.eraYear }`);
+ assert.sameValue(`subtract from end-of-month ${ unit } ${ id } era: ${ startReverseNextDay.era }`, `subtract from end-of-month ${ unit } ${ id } era: ${ start.era }`);
+ assert.sameValue(`subtract from end-of-month ${ unit } ${ id } year: ${ startReverseNextDay.year }`, `subtract from end-of-month ${ unit } ${ id } year: ${ start.year }`);
+ assert.sameValue(`subtract from end-of-month ${ unit } ${ id } month: ${ startReverseNextDay.month }`, `subtract from end-of-month ${ unit } ${ id } month: ${ start.month }`);
+ assert.sameValue(`subtract from end-of-month ${ unit } ${ id } monthCode: ${ startReverseNextDay.monthCode }`, `subtract from end-of-month ${ unit } ${ id } monthCode: ${ start.monthCode }`);
+ }
+ var ms = (globalThis.performance ? globalThis.performance.now() : Date.now()) - now;
+ totalNow += ms;
+ if (logPerf)
+ console.log(`${ id } add ${ duration }: ${ ms.toFixed(2) }ms, total: ${ totalNow.toFixed(2) }ms`);
+ };
+ }
+}
+var daysInMonthCases = {
+ iso8601: {
+ year: 2001,
+ leap: false,
+ days: [
+ 31,
+ 28,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31
+ ]
+ },
+ buddhist: {
+ year: 4001,
+ leap: false,
+ days: [
+ 31,
+ 28,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31
+ ]
+ },
+ chinese: {
+ year: 2001,
+ leap: "M04L",
+ days: [
+ 30,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30
+ ]
+ },
+ coptic: {
+ year: 2001,
+ leap: false,
+ days: [
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 5
+ ]
+ },
+ dangi: {
+ year: 2001,
+ leap: "M04L",
+ days: [
+ 30,
+ 30,
+ 30,
+ 29,
+ 29,
+ 30,
+ 29,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30
+ ]
+ },
+ ethioaa: {
+ year: 2001,
+ leap: false,
+ days: [
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 5
+ ]
+ },
+ ethiopic: {
+ year: 2001,
+ leap: false,
+ days: [
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 5
+ ]
+ },
+ gregory: {
+ year: 2001,
+ leap: false,
+ days: [
+ 31,
+ 28,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31
+ ]
+ },
+ hebrew: {
+ year: 2001,
+ leap: "M05L",
+ days: [
+ 30,
+ 30,
+ 30,
+ 29,
+ 30,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29
+ ]
+ },
+ indian: {
+ year: 2001,
+ leap: false,
+ days: [
+ 30,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30
+ ]
+ },
+ islamic: {
+ year: 2001,
+ leap: false,
+ days: [
+ 29,
+ 30,
+ 29,
+ 29,
+ 30,
+ 29,
+ 30,
+ 30,
+ 29,
+ 30,
+ 30,
+ 29
+ ]
+ },
+ "islamic-umalqura": {
+ year: 2001,
+ leap: true,
+ days: [
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 30
+ ]
+ },
+ "islamic-tbla": {
+ year: 2001,
+ leap: true,
+ days: [
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 30
+ ]
+ },
+ "islamic-civil": {
+ year: 2001,
+ leap: true,
+ days: [
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 30
+ ]
+ },
+ "islamic-rgsa": {
+ year: 2001,
+ leap: false,
+ days: [
+ 29,
+ 30,
+ 29,
+ 29,
+ 30,
+ 29,
+ 30,
+ 30,
+ 29,
+ 30,
+ 30,
+ 29
+ ]
+ },
+ islamicc: {
+ year: 2001,
+ leap: true,
+ days: [
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 29,
+ 30,
+ 30
+ ]
+ },
+ japanese: {
+ year: 2001,
+ leap: false,
+ days: [
+ 31,
+ 28,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31
+ ]
+ },
+ persian: {
+ year: 2001,
+ leap: false,
+ days: [
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 30,
+ 30,
+ 30,
+ 30,
+ 30,
+ 29
+ ]
+ },
+ roc: {
+ year: 2001,
+ leap: true,
+ days: [
+ 31,
+ 29,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31
+ ]
+ }
+};
+totalNow = 0;
+for (var id of calendars) {
+ var {year, leap, days} = daysInMonthCases[id];
+ var date = hasOutdatedChineseIcuData && (id === "chinese" || id === "dangi") ? undefined : Temporal.PlainDate.from({
+ year,
+ month: 1,
+ day: 1,
+ calendar: id
+ });
+ if ((id === "chinese" || id === "dangi") && hasOutdatedChineseIcuData ) {
+ if (typeof leap === "boolean") {
+ assert.sameValue(date.inLeapYear, leap);
+ } else {
+ assert.sameValue(date.inLeapYear, true);
+ var leapMonth = date.with({ monthCode: leap });
+ assert.sameValue(leapMonth.monthCode, leap);
+ }
+ };
+ if ((id === "chinese" || id === "dangi") && hasOutdatedChineseIcuData ) {
+ var now = globalThis.performance ? globalThis.performance.now() : Date.now();
+ var {monthsInYear} = date;
+ assert.sameValue(monthsInYear, days.length);
+ for (var i = monthsInYear, leapMonthIndex = undefined, monthStart = undefined; i >= 1; i--) {
+ monthStart = monthStart ? monthStart.add({ months: -1 }) : date.add({ months: monthsInYear - 1 });
+ var {month, monthCode, daysInMonth} = monthStart;
+ assert.sameValue(`${ id } month ${ i } (code ${ monthCode }) days: ${ daysInMonth }`, `${ id } month ${ i } (code ${ monthCode }) days: ${ days[i - 1] }`);
+ if (monthCode.endsWith("L")) {
+ assert.sameValue(date.with({ monthCode }).monthCode, monthCode);
+ leapMonthIndex = i;
+ } else {
+ if (leapMonthIndex && i === leapMonthIndex - 1) {
+ var inLeapMonth = monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` });
+ assert.sameValue(inLeapMonth.monthCode, `${ monthCode }L`);
+ } else {
+ assert.throws(RangeError, () => monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` }, { overflow: "reject" }));
+ if ([
+ "chinese",
+ "dangi"
+ ].includes(id)) {
+ if (i === 1 || i === 12 || i === 13) {
+ assert.throws(RangeError, () => monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` }));
+ } else {
+ var fakeL = monthStart.with({
+ monthCode: `M${ month.toString().padStart(2, "0") }L`,
+ day: 5
+ });
+ assert.sameValue(`fake leap month ${ fakeL.monthCode }`, `fake leap month M${ month.toString().padStart(2, "0") }`);
+ assert.sameValue(fakeL.day, fakeL.daysInMonth);
+ }
+ }
+ }
+ if (![
+ "chinese",
+ "dangi",
+ "hebrew"
+ ].includes(id)) {
+ assert.throws(RangeError, () => monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` }));
+ }
+ }
+ assert.throws(RangeError, () => monthStart.with({ day: daysInMonth + 1 }, { overflow: "reject" }));
+ var oneDayPastMonthEnd = monthStart.with({ day: daysInMonth + 1 });
+ assert.sameValue(oneDayPastMonthEnd.day, daysInMonth);
+ }
+ var ms = (globalThis.performance ? globalThis.performance.now() : Date.now()) - now;
+ totalNow += ms;
+ if (logPerf)
+ console.log(`${ id } months check ${ id }: ${ ms.toFixed(2) }ms, total: ${ totalNow.toFixed(2) }ms`);
+ };
+}
+var monthDayCases = [
+ {
+ calendar: "iso8601",
+ isoReferenceYear: 1972,
+ year: 2004,
+ month: 2,
+ day: 29
+ },
+ {
+ calendar: "buddhist",
+ isoReferenceYear: 1972,
+ year: 2004,
+ month: 2,
+ day: 29
+ },
+ {
+ calendar: "chinese",
+ isoReferenceYear: 1963,
+ year: 2001,
+ month: 5,
+ monthCode: "M04L",
+ day: 15
+ },
+ {
+ calendar: "chinese",
+ isoReferenceYear: 1971,
+ year: 2000,
+ month: 6,
+ day: 30
+ },
+ {
+ calendar: "coptic",
+ isoReferenceYear: 1971,
+ year: 2006,
+ month: 13,
+ day: 6
+ },
+ {
+ calendar: "dangi",
+ isoReferenceYear: 1963,
+ year: 2001,
+ month: 5,
+ monthCode: "M04L",
+ day: 15
+ },
+ {
+ calendar: "dangi",
+ isoReferenceYear: 1971,
+ year: 2000,
+ month: 6,
+ day: 30
+ },
+ {
+ calendar: "ethiopic",
+ isoReferenceYear: 1971,
+ year: 2006,
+ month: 13,
+ day: 6
+ },
+ {
+ calendar: "ethioaa",
+ isoReferenceYear: 1971,
+ year: 2006,
+ month: 13,
+ day: 6
+ },
+ {
+ calendar: "gregory",
+ isoReferenceYear: 1972,
+ year: 2004,
+ month: 2,
+ day: 29
+ },
+ {
+ calendar: "hebrew",
+ isoReferenceYear: 1970,
+ year: 5779,
+ month: 6,
+ monthCode: "M05L",
+ day: 15
+ },
+ {
+ calendar: "hebrew",
+ isoReferenceYear: 1971,
+ year: 5776,
+ month: 2,
+ day: 30
+ },
+ {
+ calendar: "hebrew",
+ isoReferenceYear: 1971,
+ year: 5772,
+ month: 3,
+ day: 30
+ },
+ {
+ calendar: "indian",
+ isoReferenceYear: 1968,
+ year: 2002,
+ month: 1,
+ day: 31
+ },
+ {
+ calendar: "islamic",
+ isoReferenceYear: 1970,
+ year: 2001,
+ month: 1,
+ day: 30
+ },
+ {
+ calendar: "islamic-umalqura",
+ isoReferenceYear: 1969,
+ year: 2001,
+ month: 1,
+ day: 30
+ },
+ {
+ calendar: "islamic-tbla",
+ isoReferenceYear: 1971,
+ year: 2001,
+ month: 1,
+ day: 30
+ },
+ {
+ calendar: "islamic-civil",
+ isoReferenceYear: 1971,
+ year: 2001,
+ month: 1,
+ day: 30
+ },
+ {
+ calendar: "islamic-rgsa",
+ isoReferenceYear: 1970,
+ year: 2001,
+ month: 1,
+ day: 30
+ },
+ {
+ calendar: "islamicc",
+ isoReferenceYear: 1971,
+ year: 2001,
+ month: 1,
+ day: 30
+ },
+ {
+ calendar: "japanese",
+ isoReferenceYear: 1972,
+ year: 2004,
+ month: 2,
+ day: 29
+ },
+ {
+ calendar: "persian",
+ isoReferenceYear: 1972,
+ year: 2004,
+ month: 12,
+ day: 30
+ },
+ {
+ calendar: "roc",
+ isoReferenceYear: 1972,
+ year: 93,
+ month: 2,
+ day: 29
+ }
+];
+var i = 0;
+for (var test of monthDayCases) {
+ var id = test.calendar;
+ if ((id === "chinese" || id === "dangi") && hasOutdatedChineseIcuData ) {
+ if (test.monthCode === undefined)
+ test.monthCode = `M${ test.month.toString().padStart(2, "0") }`;
+ var {calendar, monthCode, month, day, year, isoReferenceYear} = test;
+ var md = Temporal.PlainMonthDay.from({
+ year,
+ month,
+ day,
+ calendar
+ });
+ var isoString = md.toString();
+ var mdFromIso = Temporal.PlainMonthDay.from(isoString);
+ assert.sameValue(mdFromIso, md);
+ var isoFields = md.getISOFields();
+ assert.sameValue(md.monthCode, monthCode);
+ assert.sameValue(md.day, day);
+ assert.sameValue(isoFields.isoYear, isoReferenceYear);
+ var md2 = Temporal.PlainMonthDay.from({
+ monthCode,
+ day,
+ calendar
+ });
+ var isoFields2 = md2.getISOFields();
+ assert.sameValue(md2.monthCode, monthCode);
+ assert.sameValue(md2.day, day);
+ assert.sameValue(isoFields2.isoYear, isoReferenceYear);
+ assert.sameValue(md.equals(md2), true);
+ assert.throws(RangeError, () => {
+ Temporal.PlainMonthDay.from({
+ monthCode: "M15",
+ day: 1,
+ calendar
+ }, { overflow: "reject" });
+ });
+ assert.throws(RangeError, () => {
+ Temporal.PlainMonthDay.from({
+ monthCode: "M15",
+ day: 1,
+ calendar
+ });
+ });
+ assert.throws(RangeError, () => {
+ Temporal.PlainMonthDay.from({
+ year,
+ month: 15,
+ day: 1,
+ calendar
+ }, { overflow: "reject" });
+ });
+ var constrained = Temporal.PlainMonthDay.from({
+ year,
+ month: 15,
+ day: 1,
+ calendar
+ });
+ var {monthCode: monthCodeConstrained} = constrained;
+ assert(monthCodeConstrained === "M12" || monthCodeConstrained === "M13");
+ };
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/persian-calendar.js b/js/src/tests/test262/staging/Intl402/Temporal/old/persian-calendar.js
new file mode 100644
index 0000000000..a3578f3208
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/persian-calendar.js
@@ -0,0 +1,93 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2023 Justin Grant. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: Persian calendar
+features: [Temporal]
+---*/
+
+// Test data obtained from ICU
+
+const tests = [
+ {
+ testYear: 1395,
+ inLeapYear: true,
+ daysInYear: 366,
+ daysInMonth12: 30,
+ isoYear: 2016,
+ isoMonth: 3,
+ isoDay: 20
+ },
+ {
+ testYear: 1396,
+ inLeapYear: false,
+ daysInYear: 365,
+ daysInMonth12: 29,
+ isoYear: 2017,
+ isoMonth: 3,
+ isoDay: 21
+ },
+ {
+ testYear: 1397,
+ inLeapYear: false,
+ daysInYear: 365,
+ daysInMonth12: 29,
+ isoYear: 2018,
+ isoMonth: 3,
+ isoDay: 21
+ },
+ {
+ testYear: 1398,
+ inLeapYear: false,
+ daysInYear: 365,
+ daysInMonth12: 29,
+ isoYear: 2019,
+ isoMonth: 3,
+ isoDay: 21
+ },
+ {
+ testYear: 1399,
+ inLeapYear: true,
+ daysInYear: 366,
+ daysInMonth12: 30,
+ isoYear: 2020,
+ isoMonth: 3,
+ isoDay: 20
+ },
+ {
+ testYear: 1400,
+ inLeapYear: false,
+ daysInYear: 365,
+ daysInMonth12: 29,
+ isoYear: 2021,
+ isoMonth: 3,
+ isoDay: 21
+ }
+];
+
+for (const test of tests) {
+ const { testYear, inLeapYear, daysInYear, daysInMonth12, isoYear, isoMonth, isoDay } = test;
+ const date = Temporal.PlainDate.from({ year: testYear, month: 1, day: 1, calendar: "persian" });
+ const isoFields = date.getISOFields();
+ assert.sameValue(date.calendarId, "persian");
+ assert.sameValue(date.year, testYear);
+ assert.sameValue(date.month, 1);
+ assert.sameValue(date.monthCode, "M01");
+ assert.sameValue(date.day, 1);
+ assert.sameValue(date.inLeapYear, inLeapYear);
+ assert.sameValue(date.daysInYear, daysInYear);
+ assert.sameValue(date.monthsInYear, 12);
+ assert.sameValue(date.dayOfYear, 1);
+ const startOfNextYear = date.with({ year: testYear + 1 });
+ const lastDayOfThisYear = startOfNextYear.subtract({ days: 1 });
+ assert.sameValue(lastDayOfThisYear.dayOfYear, daysInYear);
+ const dateMonth12 = date.with({ month: 12 });
+ assert.sameValue(dateMonth12.daysInMonth, daysInMonth12);
+ assert.sameValue(isoYear, isoFields.isoYear);
+ assert.sameValue(isoMonth, isoFields.isoMonth);
+ assert.sameValue(isoDay, isoFields.isoDay);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/shell.js b/js/src/tests/test262/staging/Intl402/Temporal/old/shell.js
new file mode 100644
index 0000000000..276ee734ff
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/shell.js
@@ -0,0 +1,329 @@
+// GENERATED, DO NOT EDIT
+// file: deepEqual.js
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Compare two values structurally
+defines: [assert.deepEqual]
+---*/
+
+assert.deepEqual = function(actual, expected, message) {
+ var format = assert.deepEqual.format;
+ assert(
+ assert.deepEqual._compare(actual, expected),
+ `Expected ${format(actual)} to be structurally equal to ${format(expected)}. ${(message || '')}`
+ );
+};
+
+assert.deepEqual.format = function(value, seen) {
+ switch (typeof value) {
+ case 'string':
+ return typeof JSON !== "undefined" ? JSON.stringify(value) : `"${value}"`;
+ case 'number':
+ case 'boolean':
+ case 'symbol':
+ case 'bigint':
+ return value.toString();
+ case 'undefined':
+ return 'undefined';
+ case 'function':
+ return `[Function${value.name ? `: ${value.name}` : ''}]`;
+ case 'object':
+ if (value === null) return 'null';
+ if (value instanceof Date) return `Date "${value.toISOString()}"`;
+ if (value instanceof RegExp) return value.toString();
+ if (!seen) {
+ seen = {
+ counter: 0,
+ map: new Map()
+ };
+ }
+
+ let usage = seen.map.get(value);
+ if (usage) {
+ usage.used = true;
+ return `[Ref: #${usage.id}]`;
+ }
+
+ usage = { id: ++seen.counter, used: false };
+ seen.map.set(value, usage);
+
+ if (typeof Set !== "undefined" && value instanceof Set) {
+ return `Set {${Array.from(value).map(value => assert.deepEqual.format(value, seen)).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`;
+ }
+ if (typeof Map !== "undefined" && value instanceof Map) {
+ return `Map {${Array.from(value).map(pair => `${assert.deepEqual.format(pair[0], seen)} => ${assert.deepEqual.format(pair[1], seen)}}`).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`;
+ }
+ if (Array.isArray ? Array.isArray(value) : value instanceof Array) {
+ return `[${value.map(value => assert.deepEqual.format(value, seen)).join(', ')}]${usage.used ? ` as #${usage.id}` : ''}`;
+ }
+ let tag = Symbol.toStringTag in value ? value[Symbol.toStringTag] : 'Object';
+ if (tag === 'Object' && Object.getPrototypeOf(value) === null) {
+ tag = '[Object: null prototype]';
+ }
+ return `${tag ? `${tag} ` : ''}{ ${Object.keys(value).map(key => `${key.toString()}: ${assert.deepEqual.format(value[key], seen)}`).join(', ')} }${usage.used ? ` as #${usage.id}` : ''}`;
+ default:
+ return typeof value;
+ }
+};
+
+assert.deepEqual._compare = (function () {
+ var EQUAL = 1;
+ var NOT_EQUAL = -1;
+ var UNKNOWN = 0;
+
+ function deepEqual(a, b) {
+ return compareEquality(a, b) === EQUAL;
+ }
+
+ function compareEquality(a, b, cache) {
+ return compareIf(a, b, isOptional, compareOptionality)
+ || compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
+ || compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
+ || NOT_EQUAL;
+ }
+
+ function compareIf(a, b, test, compare, cache) {
+ return !test(a)
+ ? !test(b) ? UNKNOWN : NOT_EQUAL
+ : !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
+ }
+
+ function tryCompareStrictEquality(a, b) {
+ return a === b ? EQUAL : UNKNOWN;
+ }
+
+ function tryCompareTypeOfEquality(a, b) {
+ return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
+ }
+
+ function tryCompareToStringTagEquality(a, b) {
+ var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
+ var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
+ return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
+ }
+
+ function isOptional(value) {
+ return value === undefined
+ || value === null;
+ }
+
+ function compareOptionality(a, b) {
+ return tryCompareStrictEquality(a, b)
+ || NOT_EQUAL;
+ }
+
+ function isPrimitiveEquatable(value) {
+ switch (typeof value) {
+ case 'string':
+ case 'number':
+ case 'bigint':
+ case 'boolean':
+ case 'symbol':
+ return true;
+ default:
+ return isBoxed(value);
+ }
+ }
+
+ function comparePrimitiveEquality(a, b) {
+ if (isBoxed(a)) a = a.valueOf();
+ if (isBoxed(b)) b = b.valueOf();
+ return tryCompareStrictEquality(a, b)
+ || tryCompareTypeOfEquality(a, b)
+ || compareIf(a, b, isNaNEquatable, compareNaNEquality)
+ || NOT_EQUAL;
+ }
+
+ function isNaNEquatable(value) {
+ return typeof value === 'number';
+ }
+
+ function compareNaNEquality(a, b) {
+ return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
+ }
+
+ function isObjectEquatable(value) {
+ return typeof value === 'object';
+ }
+
+ function compareObjectEquality(a, b, cache) {
+ if (!cache) cache = new Map();
+ return getCache(cache, a, b)
+ || setCache(cache, a, b, EQUAL) // consider equal for now
+ || cacheComparison(a, b, tryCompareStrictEquality, cache)
+ || cacheComparison(a, b, tryCompareToStringTagEquality, cache)
+ || compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
+ || compareIf(a, b, isToStringEquatable, compareToStringEquality)
+ || compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
+ || compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
+ || compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
+ || cacheComparison(a, b, fail, cache);
+ }
+
+ function isBoxed(value) {
+ return value instanceof String
+ || value instanceof Number
+ || value instanceof Boolean
+ || typeof Symbol === 'function' && value instanceof Symbol
+ || typeof BigInt === 'function' && value instanceof BigInt;
+ }
+
+ function isValueOfEquatable(value) {
+ return value instanceof Date;
+ }
+
+ function compareValueOfEquality(a, b) {
+ return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
+ || NOT_EQUAL;
+ }
+
+ function isToStringEquatable(value) {
+ return value instanceof RegExp;
+ }
+
+ function compareToStringEquality(a, b) {
+ return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
+ || NOT_EQUAL;
+ }
+
+ function isArrayLikeEquatable(value) {
+ return (Array.isArray ? Array.isArray(value) : value instanceof Array)
+ || (typeof Uint8Array === 'function' && value instanceof Uint8Array)
+ || (typeof Uint8ClampedArray === 'function' && value instanceof Uint8ClampedArray)
+ || (typeof Uint16Array === 'function' && value instanceof Uint16Array)
+ || (typeof Uint32Array === 'function' && value instanceof Uint32Array)
+ || (typeof Int8Array === 'function' && value instanceof Int8Array)
+ || (typeof Int16Array === 'function' && value instanceof Int16Array)
+ || (typeof Int32Array === 'function' && value instanceof Int32Array)
+ || (typeof Float32Array === 'function' && value instanceof Float32Array)
+ || (typeof Float64Array === 'function' && value instanceof Float64Array)
+ || (typeof BigUint64Array === 'function' && value instanceof BigUint64Array)
+ || (typeof BigInt64Array === 'function' && value instanceof BigInt64Array);
+ }
+
+ function compareArrayLikeEquality(a, b, cache) {
+ if (a.length !== b.length) return NOT_EQUAL;
+ for (var i = 0; i < a.length; i++) {
+ if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
+ return NOT_EQUAL;
+ }
+ }
+ return EQUAL;
+ }
+
+ function isStructurallyEquatable(value) {
+ return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference
+ || typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference
+ || typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference
+ || typeof Map === 'function' && value instanceof Map // comparable via @@iterator
+ || typeof Set === 'function' && value instanceof Set); // comparable via @@iterator
+ }
+
+ function compareStructuralEquality(a, b, cache) {
+ var aKeys = [];
+ for (var key in a) aKeys.push(key);
+
+ var bKeys = [];
+ for (var key in b) bKeys.push(key);
+
+ if (aKeys.length !== bKeys.length) {
+ return NOT_EQUAL;
+ }
+
+ aKeys.sort();
+ bKeys.sort();
+
+ for (var i = 0; i < aKeys.length; i++) {
+ var aKey = aKeys[i];
+ var bKey = bKeys[i];
+ if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) {
+ return NOT_EQUAL;
+ }
+ if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) {
+ return NOT_EQUAL;
+ }
+ }
+
+ return compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
+ || EQUAL;
+ }
+
+ function isIterableEquatable(value) {
+ return typeof Symbol === 'function'
+ && typeof value[Symbol.iterator] === 'function';
+ }
+
+ function compareIteratorEquality(a, b, cache) {
+ if (typeof Map === 'function' && a instanceof Map && b instanceof Map ||
+ typeof Set === 'function' && a instanceof Set && b instanceof Set) {
+ if (a.size !== b.size) return NOT_EQUAL; // exit early if we detect a difference in size
+ }
+
+ var ar, br;
+ while (true) {
+ ar = a.next();
+ br = b.next();
+ if (ar.done) {
+ if (br.done) return EQUAL;
+ if (b.return) b.return();
+ return NOT_EQUAL;
+ }
+ if (br.done) {
+ if (a.return) a.return();
+ return NOT_EQUAL;
+ }
+ if (compareEquality(ar.value, br.value, cache) === NOT_EQUAL) {
+ if (a.return) a.return();
+ if (b.return) b.return();
+ return NOT_EQUAL;
+ }
+ }
+ }
+
+ function compareIterableEquality(a, b, cache) {
+ return compareIteratorEquality(a[Symbol.iterator](), b[Symbol.iterator](), cache);
+ }
+
+ function cacheComparison(a, b, compare, cache) {
+ var result = compare(a, b, cache);
+ if (cache && (result === EQUAL || result === NOT_EQUAL)) {
+ setCache(cache, a, b, /** @type {EQUAL | NOT_EQUAL} */(result));
+ }
+ return result;
+ }
+
+ function fail() {
+ return NOT_EQUAL;
+ }
+
+ function setCache(cache, left, right, result) {
+ var otherCache;
+
+ otherCache = cache.get(left);
+ if (!otherCache) cache.set(left, otherCache = new Map());
+ otherCache.set(right, result);
+
+ otherCache = cache.get(right);
+ if (!otherCache) cache.set(right, otherCache = new Map());
+ otherCache.set(left, result);
+ }
+
+ function getCache(cache, left, right) {
+ var otherCache;
+ var result;
+
+ otherCache = cache.get(left);
+ result = otherCache && otherCache.get(right);
+ if (result) return result;
+
+ otherCache = cache.get(right);
+ result = otherCache && otherCache.get(left);
+ if (result) return result;
+
+ return UNKNOWN;
+ }
+
+ return deepEqual;
+})();
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/time-toLocaleString.js b/js/src/tests/test262/staging/Intl402/Temporal/old/time-toLocaleString.js
new file mode 100644
index 0000000000..a521123333
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/time-toLocaleString.js
@@ -0,0 +1,30 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-zoneddatetime-objects
+description: time.toLocaleString()
+features: [Temporal]
+---*/
+
+// Tolerate implementation variance by expecting consistency without being prescriptive.
+// TODO: can we change tests to be less reliant on CLDR formats while still testing that
+// Temporal and Intl are behaving as expected?
+const usDayPeriodSpace =
+ new Intl.DateTimeFormat("en-US", { timeStyle: "short" })
+ .formatToParts(0)
+ .find((part, i, parts) => part.type === "literal" && parts[i + 1].type === "dayPeriod")?.value || "";
+
+var time = Temporal.PlainTime.from("1976-11-18T15:23:30");
+assert.sameValue(`${time.toLocaleString("en-US", { timeZone: "America/New_York" })}`, `3:23:30${usDayPeriodSpace}PM`);
+assert.sameValue(`${time.toLocaleString("de-AT", { timeZone: "Europe/Vienna" })}`, "15:23:30");
+
+// should ignore units not in the data type
+assert.sameValue(time.toLocaleString("en-US", { timeZoneName: "long" }), `3:23:30${usDayPeriodSpace}PM`);
+assert.sameValue(time.toLocaleString("en-US", { year: "numeric" }), `3:23:30${usDayPeriodSpace}PM`);
+assert.sameValue(time.toLocaleString("en-US", { month: "numeric" }), `3:23:30${usDayPeriodSpace}PM`);
+assert.sameValue(time.toLocaleString("en-US", { day: "numeric" }), `3:23:30${usDayPeriodSpace}PM`);
+assert.sameValue(time.toLocaleString("en-US", { weekday: "long" }), `3:23:30${usDayPeriodSpace}PM`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/timezone-america-la.js b/js/src/tests/test262/staging/Intl402/Temporal/old/timezone-america-la.js
new file mode 100644
index 0000000000..662f54d05c
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/timezone-america-la.js
@@ -0,0 +1,31 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-timezone-objects
+description: America/Los_Angeles
+features: [Temporal]
+---*/
+
+var zone = new Temporal.TimeZone("America/Los_Angeles");
+var inst = new Temporal.Instant(0n);
+var dtm = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789);
+assert.sameValue(zone.id, `${ zone }`)
+assert.sameValue(zone.getOffsetNanosecondsFor(inst), -8 * 3600000000000)
+assert.sameValue(zone.getOffsetStringFor(inst), "-08:00")
+assert(zone.getInstantFor(dtm) instanceof Temporal.Instant)
+for (var i = 0, txn = inst; i < 4; i++) {
+ var transition = zone.getNextTransition(txn);
+ assert(transition instanceof Temporal.Instant);
+ assert(!transition.equals(txn));
+ txn = transition;
+}
+for (var i = 0, txn = inst; i < 4; i++) {
+ var transition = zone.getPreviousTransition(txn);
+ assert(transition instanceof Temporal.Instant);
+ assert(!transition.equals(txn));
+ txn = transition;
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-string-parsing.js b/js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-string-parsing.js
new file mode 100644
index 0000000000..16690270bc
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-string-parsing.js
@@ -0,0 +1,101 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-zoneddatetime-objects
+description: String parsing cases that require a TZDB in the implementation
+features: [Temporal]
+---*/
+
+// parses with an IANA zone but no offset (with disambiguation)
+var zdt = Temporal.ZonedDateTime.from("2020-03-08T02:30[America/Los_Angeles]", { disambiguation: "earlier" });
+assert.sameValue(zdt.toString(), "2020-03-08T01:30:00-08:00[America/Los_Angeles]");
+
+// "Z" means preserve the exact time in the given IANA time zone
+var zdt = Temporal.ZonedDateTime.from("2020-03-08T09:00:00Z[America/Los_Angeles]");
+assert.sameValue(zdt.toString(), "2020-03-08T01:00:00-08:00[America/Los_Angeles]");
+
+// Offset options
+
+// { offset: 'prefer' } if offset matches time zone (first 1:30 when DST ends)
+var zdt = Temporal.ZonedDateTime.from("2020-11-01T01:30-07:00[America/Los_Angeles]", { offset: "prefer" });
+assert.sameValue(zdt.toString(), "2020-11-01T01:30:00-07:00[America/Los_Angeles]");
+
+// { offset: 'prefer' } if offset matches time zone (second 1:30 when DST ends)
+var zdt = Temporal.ZonedDateTime.from("2020-11-01T01:30-08:00[America/Los_Angeles]", { offset: "prefer" });
+assert.sameValue(zdt.toString(), "2020-11-01T01:30:00-08:00[America/Los_Angeles]");
+
+// { offset: 'prefer' } if offset does not match time zone
+var zdt = Temporal.ZonedDateTime.from("2020-11-01T04:00-07:00[America/Los_Angeles]", { offset: "prefer" });
+assert.sameValue(zdt.toString(), "2020-11-01T04:00:00-08:00[America/Los_Angeles]");
+
+// { offset: 'ignore' } uses time zone only
+var zdt = Temporal.ZonedDateTime.from("2020-11-01T04:00-12:00[America/Los_Angeles]", { offset: "ignore" });
+assert.sameValue(zdt.toString(), "2020-11-01T04:00:00-08:00[America/Los_Angeles]");
+
+// { offset: 'use' } uses offset only
+var zdt = Temporal.ZonedDateTime.from("2020-11-01T04:00-07:00[America/Los_Angeles]", { offset: "use" });
+assert.sameValue(zdt.toString(), "2020-11-01T03:00:00-08:00[America/Los_Angeles]");
+
+// Disambiguation options
+
+// plain datetime with multiple instants - Fall DST in Brazil
+var str = "2019-02-16T23:45[America/Sao_Paulo]";
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str) }`, "2019-02-16T23:45:00-02:00[America/Sao_Paulo]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { disambiguation: "compatible" }) }`, "2019-02-16T23:45:00-02:00[America/Sao_Paulo]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { disambiguation: "earlier" }) }`, "2019-02-16T23:45:00-02:00[America/Sao_Paulo]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { disambiguation: "later" }) }`, "2019-02-16T23:45:00-03:00[America/Sao_Paulo]");
+assert.throws(RangeError, () => Temporal.ZonedDateTime.from(str, { disambiguation: "reject" }));
+
+// plain datetime with multiple instants - Spring DST in Los Angeles
+var str = "2020-03-08T02:30[America/Los_Angeles]";
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { disambiguation: "compatible" }) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { disambiguation: "earlier" }) }`, "2020-03-08T01:30:00-08:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { disambiguation: "later" }) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.throws(RangeError, () => Temporal.ZonedDateTime.from(str, { disambiguation: "reject" }));
+
+// uses disambiguation if offset is ignored
+var str = "2020-03-08T02:30[America/Los_Angeles]";
+var offset = "ignore";
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { offset }) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "compatible"
+}) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "earlier"
+}) }`, "2020-03-08T01:30:00-08:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "later"
+}) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.throws(RangeError, () => Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "reject"
+}));
+
+// uses disambiguation if offset is wrong and option is prefer
+var str = "2020-03-08T02:30-23:59[America/Los_Angeles]";
+var offset = "prefer";
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, { offset }) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "compatible"
+}) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "earlier"
+}) }`, "2020-03-08T01:30:00-08:00[America/Los_Angeles]");
+assert.sameValue(`${ Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "later"
+}) }`, "2020-03-08T03:30:00-07:00[America/Los_Angeles]");
+assert.throws(RangeError, () => Temporal.ZonedDateTime.from(str, {
+ offset,
+ disambiguation: "reject"
+}));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-transitions.js b/js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-transitions.js
new file mode 100644
index 0000000000..52978e40fb
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/tzdb-transitions.js
@@ -0,0 +1,47 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-timezone-objects
+description: Tests that are impractical to do without a TZDB
+features: [Temporal]
+---*/
+
+// getNextTransition()
+
+var nyc = Temporal.TimeZone.from("America/New_York");
+
+// should not have bug #510
+var a1 = Temporal.Instant.from("2019-04-16T21:01Z");
+var a2 = Temporal.Instant.from("1800-01-01T00:00Z");
+assert.sameValue(nyc.getNextTransition(a1).toString(), "2019-11-03T06:00:00Z");
+assert.sameValue(nyc.getNextTransition(a2).toString(), "1883-11-18T17:00:00Z");
+
+// should not return the same as its input if the input is a transition point
+var inst = Temporal.Instant.from("2019-01-01T00:00Z");
+assert.sameValue(`${ nyc.getNextTransition(inst) }`, "2019-03-10T07:00:00Z");
+assert.sameValue(`${ nyc.getNextTransition(nyc.getNextTransition(inst)) }`, "2019-11-03T06:00:00Z");
+
+// casts argument
+assert.sameValue(`${ nyc.getNextTransition("2019-04-16T21:01Z") }`, "2019-11-03T06:00:00Z");
+
+// getPreviousTransition()
+
+var london = Temporal.TimeZone.from("Europe/London");
+
+// should return first and last transition
+var a1 = Temporal.Instant.from("2020-06-11T21:01Z");
+var a2 = Temporal.Instant.from("1848-01-01T00:00Z");
+assert.sameValue(london.getPreviousTransition(a1).toString(), "2020-03-29T01:00:00Z");
+assert.sameValue(london.getPreviousTransition(a2).toString(), "1847-12-01T00:01:15Z");
+
+// should not return the same as its input if the input is a transition point
+var inst = Temporal.Instant.from("2020-06-01T00:00Z");
+assert.sameValue(`${ london.getPreviousTransition(inst) }`, "2020-03-29T01:00:00Z");
+assert.sameValue(`${ london.getPreviousTransition(london.getPreviousTransition(inst)) }`, "2019-10-27T01:00:00Z");
+
+// casts argument
+assert.sameValue(`${ london.getPreviousTransition("2020-06-11T21:01Z") }`, "2020-03-29T01:00:00Z");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js b/js/src/tests/test262/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js
new file mode 100644
index 0000000000..c92aa506d5
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js
@@ -0,0 +1,42 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-intl
+description: yearmonth.toLocaleString()
+features: [Temporal]
+---*/
+
+// Tolerate implementation variance by expecting consistency without being prescriptive.
+// TODO: can we change tests to be less reliant on CLDR formats while still testing that
+// Temporal and Intl are behaving as expected?
+// Workarounds for https://unicode-org.atlassian.net/browse/CLDR-16243
+const deMonthDayRangeSeparator = new Intl.DateTimeFormat("de-AT", { month: "numeric", day: "numeric" })
+ .formatRangeToParts(1 * 86400 * 1000, 90 * 86400 * 1000)
+ .find((part) => part.type === "literal" && part.source === "shared").value;
+const deMonthYearSeparator = new Intl.DateTimeFormat("de-AT", { year: "numeric", month: "numeric" })
+ .formatToParts(0)
+ .find((part) => part.type === "literal").value;
+
+var calendar = new Intl.DateTimeFormat("en-US").resolvedOptions().calendar;
+var yearmonth = Temporal.PlainYearMonth.from({
+ year: 1976,
+ month: 11,
+ calendar
+});
+assert.sameValue(`${yearmonth.toLocaleString("en-US", { timeZone: "America/New_York" })}`, "11/1976");
+assert.sameValue(
+ `${yearmonth.toLocaleString("de-AT", { timeZone: "Europe/Vienna", calendar })}`,
+ `11${deMonthYearSeparator}1976`
+);
+
+// should ignore units not in the data type
+assert.sameValue(yearmonth.toLocaleString("en-US", { timeZoneName: "long" }), "11/1976");
+assert.sameValue(yearmonth.toLocaleString("en-US", { day: "numeric" }), "11/1976");
+assert.sameValue(yearmonth.toLocaleString("en-US", { hour: "numeric" }), "11/1976");
+assert.sameValue(yearmonth.toLocaleString("en-US", { minute: "numeric" }), "11/1976");
+assert.sameValue(yearmonth.toLocaleString("en-US", { second: "numeric" }), "11/1976");
+assert.sameValue(yearmonth.toLocaleString("en-US", { weekday: "long" }), "11/1976");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/old/zoneddatetime-dst-corner-cases.js b/js/src/tests/test262/staging/Intl402/Temporal/old/zoneddatetime-dst-corner-cases.js
new file mode 100644
index 0000000000..d66a8d0715
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/old/zoneddatetime-dst-corner-cases.js
@@ -0,0 +1,29 @@
+// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
+// Copyright (C) 2018 Bloomberg LP. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal-zoneddatetime-objects
+description: Corner cases of time zone offset shifts
+features: [Temporal]
+---*/
+
+// hoursInDay works with non-hour DST change
+var zdt1 = Temporal.ZonedDateTime.from("2020-10-04T12:00[Australia/Lord_Howe]");
+assert.sameValue(zdt1.hoursInDay, 23.5);
+var zdt2 = Temporal.ZonedDateTime.from("2020-04-05T12:00[Australia/Lord_Howe]");
+assert.sameValue(zdt2.hoursInDay, 24.5);
+
+// hoursInDay works with non-half-hour DST change
+var zdt = Temporal.ZonedDateTime.from("1933-01-01T12:00[Asia/Singapore]");
+assert(Math.abs(zdt.hoursInDay - 23.666666666666668) < Number.EPSILON);
+
+// hoursInDay works when day starts at 1:00 due to DST start at midnight
+var zdt = Temporal.ZonedDateTime.from("2015-10-18T12:00:00-02:00[America/Sao_Paulo]");
+assert.sameValue(zdt.hoursInDay, 23);
+
+// startOfDay works when day starts at 1:00 due to DST start at midnight
+var zdt = Temporal.ZonedDateTime.from("2015-10-18T12:00:00-02:00[America/Sao_Paulo]");
+assert.sameValue(`${ zdt.startOfDay().toPlainTime() }`, "01:00:00");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/staging/Intl402/Temporal/shell.js b/js/src/tests/test262/staging/Intl402/Temporal/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/Temporal/shell.js
diff --git a/js/src/tests/test262/staging/Intl402/browser.js b/js/src/tests/test262/staging/Intl402/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/browser.js
diff --git a/js/src/tests/test262/staging/Intl402/shell.js b/js/src/tests/test262/staging/Intl402/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/staging/Intl402/shell.js