Intl Era Monthcode: Era boundary difference in japanese calendar

Co-Authored-By: Philip Chimento <pchimento@igalia.com>
This commit is contained in:
Jesse Alama 2025-11-11 13:40:27 -08:00 committed by Ms2ger
parent 883d4ece0b
commit 34ca5ffdae
6 changed files with 1014 additions and 0 deletions

View File

@ -0,0 +1,169 @@
// Copyright (C) 2025 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindate.prototype.since
description: Date difference works correctly across era boundaries
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "japanese";
const options = { overflow: "reject" };
const bce1 = Temporal.PlainDate.from({ era: "bce", eraYear: 1, monthCode: "M06", day: 1, calendar }, options);
const ce1 = Temporal.PlainDate.from({ era: "ce", eraYear: 1, monthCode: "M06", day: 1, calendar }, options);
const ce1868 = Temporal.PlainDate.from({ era: "ce", eraYear: 1868, monthCode: "M10", day: 22, calendar }, options);
const meiji1 = Temporal.PlainDate.from({ era: "meiji", eraYear: 1, monthCode: "M10", day: 23, calendar}, options);
const meiji5 = Temporal.PlainDate.from({ era: "meiji", eraYear: 5, monthCode: "M01", day: 15, calendar }, options);
const meiji45 = Temporal.PlainDate.from({ era: "meiji", eraYear: 45, monthCode: "M05", day: 19, calendar }, options);
const taisho1 = Temporal.PlainDate.from({ era: "taisho", eraYear: 1, monthCode: "M08", day: 9, calendar }, options);
const taisho6 = Temporal.PlainDate.from({ era: "taisho", eraYear: 6, monthCode: "M03", day: 15, calendar }, options);
const taisho15 = Temporal.PlainDate.from({ era: "taisho", eraYear: 15, monthCode: "M05", day: 20, calendar }, options);
const showa1 = Temporal.PlainDate.from({ era: "showa", eraYear: 1, monthCode: "M12", day: 30, calendar }, options);
const showa55 = Temporal.PlainDate.from({ era: "showa", eraYear: 55, monthCode: "M03", day: 15, calendar }, options);
const showa64 = Temporal.PlainDate.from({ era: "showa", eraYear: 64, monthCode: "M01", day: 3, calendar }, options);
const heisei1 = Temporal.PlainDate.from({ era: "heisei", eraYear: 1, monthCode: "M02", day: 27, calendar }, options);
const heisei30 = Temporal.PlainDate.from({ era: "heisei", eraYear: 30, monthCode: "M03", day: 15, calendar }, options);
const heisei31 = Temporal.PlainDate.from({ era: "heisei", eraYear: 31, monthCode: "M04", day: 1, calendar }, options);
const reiwa1 = Temporal.PlainDate.from({ era: "reiwa", eraYear: 1, monthCode: "M06", day: 1, calendar }, options);
const reiwa2 = Temporal.PlainDate.from({ era: "reiwa", eraYear: 2, monthCode: "M03", day: 15, calendar }, options);
const tests = [
// From Heisei 30 (2018) to Reiwa 2 (2020) - crossing era boundary
[
heisei30, reiwa2,
[-2, 0, 0, 0, "-2y backwards from Heisei 30 March to Reiwa 2 March"],
[0, -24, 0, 0, "-24mo backwards from Heisei 30 March to Reiwa 2 March"],
],
[
reiwa2, heisei30,
[2, 0, 0, 0, "2y from Heisei 30 March to Reiwa 2 March"],
[0, 24, 0, 0, "24mo from Heisei 30 March to Reiwa 2 March"],
],
// Within same year but different eras
[
heisei31, reiwa1,
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
],
[
reiwa1, heisei31,
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
],
// From Showa 55 (1980) to Heisei 30 (2018) - crossing era boundary
[
showa55, heisei30,
[-38, 0, 0, 0, "-38y backwards from Showa 55 March to Heisei 30 March"],
[0, -456, 0, 0, "-456mo backwards from Showa 55 March to Heisei 30 March"],
],
[
heisei30, showa55,
[38, 0, 0, 0, "38y from Showa 55 March to Heisei 30 March"],
[0, 456, 0, 0, "456mo from Showa 55 March to Heisei 30 March"],
],
// Within same year but different eras
[
showa64, heisei1,
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
],
[
heisei1, showa64,
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
],
// From Taisho 6 (1917) to Showa 55 (1980) - crossing era boundary
[
taisho6, showa55,
[-63, 0, 0, 0, "-63y backwards from Taisho 6 March to Showa 55 March"],
[0, -756, 0, 0, "-756mo backwards from Taisho 6 March to Showa 55 March"],
],
[
showa55, taisho6,
[63, 0, 0, 0, "63y from Taisho 6 March to Showa 55 March"],
[0, 756, 0, 0, "756mo from Taisho 6 March to Showa 55 March"],
],
// Within same year but different eras
[
taisho15, showa1,
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
],
[
showa1, taisho15,
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
],
// From Meiji 5 (1872) to Taisho 6 (1917) - crossing era boundary
// Note that contemporarily January 15 1872 would have been Meiji 4 in the
// pre-1873 lunisolar calendar, but the spec-mandated behaviour is proleptic
[
meiji5, taisho6,
[-45, -2, 0, 0, "-45y -2mo backwards from Meiji 5 January to Taisho 6 March"],
[0, -542, 0, 0, "-542mo backwards from Meiji 5 January to Taisho 6 March"],
],
[
taisho6, meiji5,
[45, 2, 0, 0, "45y 2mo from Meiji 5 January to Taisho 6 March"],
[0, 542, 0, 0, "542mo from Meiji 5 January to Taisho 6 March"],
],
// Within same year but different eras
[
meiji45, taisho1,
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
],
[
taisho1, meiji45,
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
],
// Last pre-Meiji day to first day of Meiji era
[
ce1868, meiji1,
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
],
[
meiji1, ce1868,
[0, 0, 0, 1, "from day before Meiji era to first day"],
[0, 0, 0, 1, "from day before Meiji era to first day"],
],
// CE-BCE boundary
[
bce1, ce1,
[-1, 0, 0, 0, "-1y backwards from 1 BCE to 1 CE"],
[0, -12, 0, 0, "-12mo backwards from 1 BCE to 1 CE"],
],
[
ce1, bce1,
[1, 0, 0, 0, "1y from 1 BCE to 1 CE"],
[0, 12, 0, 0, "12mo from 1 BCE to 1 CE"],
],
];
for (const [one, two, yearsTest, monthsTest] of tests) {
let [years, months, weeks, days, descr] = yearsTest;
let result = one.since(two, { largestUnit: "years" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
[years, months, weeks, days, descr] = monthsTest;
result = one.since(two, { largestUnit: "months" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
const oneISO = one.withCalendar("iso8601");
const twoISO = two.withCalendar("iso8601");
const resultWeeks = one.since(two, { largestUnit: "weeks" });
const resultWeeksISO = oneISO.since(twoISO, { largestUnit: "weeks" });
TemporalHelpers.assertDurationsEqual(resultWeeks, resultWeeksISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit weeks`);
const resultDays = one.since(two);
const resultDaysISO = oneISO.since(twoISO);
TemporalHelpers.assertDurationsEqual(resultDays, resultDaysISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit days`);
}

View File

@ -0,0 +1,169 @@
// Copyright (C) 2025 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindate.prototype.until
description: Date difference works correctly across era boundaries
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "japanese";
const options = { overflow: "reject" };
const bce1 = Temporal.PlainDate.from({ era: "bce", eraYear: 1, monthCode: "M06", day: 1, calendar }, options);
const ce1 = Temporal.PlainDate.from({ era: "ce", eraYear: 1, monthCode: "M06", day: 1, calendar }, options);
const ce1868 = Temporal.PlainDate.from({ era: "ce", eraYear: 1868, monthCode: "M10", day: 22, calendar }, options);
const meiji1 = Temporal.PlainDate.from({ era: "meiji", eraYear: 1, monthCode: "M10", day: 23, calendar}, options);
const meiji5 = Temporal.PlainDate.from({ era: "meiji", eraYear: 5, monthCode: "M01", day: 15, calendar }, options);
const meiji45 = Temporal.PlainDate.from({ era: "meiji", eraYear: 45, monthCode: "M05", day: 19, calendar }, options);
const taisho1 = Temporal.PlainDate.from({ era: "taisho", eraYear: 1, monthCode: "M08", day: 9, calendar }, options);
const taisho6 = Temporal.PlainDate.from({ era: "taisho", eraYear: 6, monthCode: "M03", day: 15, calendar }, options);
const taisho15 = Temporal.PlainDate.from({ era: "taisho", eraYear: 15, monthCode: "M05", day: 20, calendar }, options);
const showa1 = Temporal.PlainDate.from({ era: "showa", eraYear: 1, monthCode: "M12", day: 30, calendar }, options);
const showa55 = Temporal.PlainDate.from({ era: "showa", eraYear: 55, monthCode: "M03", day: 15, calendar }, options);
const showa64 = Temporal.PlainDate.from({ era: "showa", eraYear: 64, monthCode: "M01", day: 3, calendar }, options);
const heisei1 = Temporal.PlainDate.from({ era: "heisei", eraYear: 1, monthCode: "M02", day: 27, calendar }, options);
const heisei30 = Temporal.PlainDate.from({ era: "heisei", eraYear: 30, monthCode: "M03", day: 15, calendar }, options);
const heisei31 = Temporal.PlainDate.from({ era: "heisei", eraYear: 31, monthCode: "M04", day: 1, calendar }, options);
const reiwa1 = Temporal.PlainDate.from({ era: "reiwa", eraYear: 1, monthCode: "M06", day: 1, calendar }, options);
const reiwa2 = Temporal.PlainDate.from({ era: "reiwa", eraYear: 2, monthCode: "M03", day: 15, calendar }, options);
const tests = [
// From Heisei 30 (2018) to Reiwa 2 (2020) - crossing era boundary
[
heisei30, reiwa2,
[2, 0, 0, 0, "2y from Heisei 30 March to Reiwa 2 March"],
[0, 24, 0, 0, "24mo from Heisei 30 March to Reiwa 2 March"],
],
[
reiwa2, heisei30,
[-2, 0, 0, 0, "-2y backwards from Heisei 30 March to Reiwa 2 March"],
[0, -24, 0, 0, "-24mo backwards from Heisei 30 March to Reiwa 2 March"],
],
// Within same year but different eras
[
heisei31, reiwa1,
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
],
[
reiwa1, heisei31,
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
],
// From Showa 55 (1980) to Heisei 30 (2018) - crossing era boundary
[
showa55, heisei30,
[38, 0, 0, 0, "38y from Showa 55 March to Heisei 30 March"],
[0, 456, 0, 0, "456mo from Showa 55 March to Heisei 30 March"],
],
[
heisei30, showa55,
[-38, 0, 0, 0, "-38y backwards from Showa 55 March to Heisei 30 March"],
[0, -456, 0, 0, "-456mo backwards from Showa 55 March to Heisei 30 March"],
],
// Within same year but different eras
[
showa64, heisei1,
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
],
[
heisei1, showa64,
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
],
// From Taisho 6 (1917) to Showa 55 (1980) - crossing era boundary
[
taisho6, showa55,
[63, 0, 0, 0, "63y from Taisho 6 March to Showa 55 March"],
[0, 756, 0, 0, "756mo from Taisho 6 March to Showa 55 March"],
],
[
showa55, taisho6,
[-63, 0, 0, 0, "-63y backwards from Taisho 6 March to Showa 55 March"],
[0, -756, 0, 0, "-756mo backwards from Taisho 6 March to Showa 55 March"],
],
// Within same year but different eras
[
taisho15, showa1,
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
],
[
showa1, taisho15,
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
],
// From Meiji 5 (1872) to Taisho 6 (1917) - crossing era boundary
// Note that contemporarily January 15 1872 would have been Meiji 4 in the
// pre-1873 lunisolar calendar, but the spec-mandated behaviour is proleptic
[
meiji5, taisho6,
[45, 2, 0, 0, "45y 2mo from Meiji 5 January to Taisho 6 March"],
[0, 542, 0, 0, "542mo from Meiji 5 January to Taisho 6 March"],
],
[
taisho6, meiji5,
[-45, -2, 0, 0, "-45y -2mo backwards from Meiji 5 January to Taisho 6 March"],
[0, -542, 0, 0, "-542mo backwards from Meiji 5 January to Taisho 6 March"],
],
// Within same year but different eras
[
meiji45, taisho1,
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
],
[
taisho1, meiji45,
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
],
// Last pre-Meiji day to first day of Meiji era
[
ce1868, meiji1,
[0, 0, 0, 1, "from day before Meiji era to first day"],
[0, 0, 0, 1, "from day before Meiji era to first day"],
],
[
meiji1, ce1868,
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
],
// CE-BCE boundary
[
bce1, ce1,
[1, 0, 0, 0, "1y from 1 BCE to 1 CE"],
[0, 12, 0, 0, "12mo from 1 BCE to 1 CE"],
],
[
ce1, bce1,
[-1, 0, 0, 0, "-1y backwards from 1 BCE to 1 CE"],
[0, -12, 0, 0, "-12mo backwards from 1 BCE to 1 CE"],
],
];
for (const [one, two, yearsTest, monthsTest] of tests) {
let [years, months, weeks, days, descr] = yearsTest;
let result = one.until(two, { largestUnit: "years" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
[years, months, weeks, days, descr] = monthsTest;
result = one.until(two, { largestUnit: "months" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
const oneISO = one.withCalendar("iso8601");
const twoISO = two.withCalendar("iso8601");
const resultWeeks = one.until(two, { largestUnit: "weeks" });
const resultWeeksISO = oneISO.until(twoISO, { largestUnit: "weeks" });
TemporalHelpers.assertDurationsEqual(resultWeeks, resultWeeksISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit weeks`);
const resultDays = one.until(two);
const resultDaysISO = oneISO.until(twoISO);
TemporalHelpers.assertDurationsEqual(resultDays, resultDaysISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit days`);
}

View File

@ -0,0 +1,169 @@
// Copyright (C) 2025 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.since
description: Date difference works correctly across era boundaries
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "japanese";
const options = { overflow: "reject" };
const bce1 = Temporal.PlainDateTime.from({ era: "bce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options);
const ce1 = Temporal.PlainDateTime.from({ era: "ce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options);
const ce1868 = Temporal.PlainDateTime.from({ era: "ce", eraYear: 1868, monthCode: "M10", day: 22, hour: 12, minute: 34, calendar }, options);
const meiji1 = Temporal.PlainDateTime.from({ era: "meiji", eraYear: 1, monthCode: "M10", day: 23, hour: 12, minute: 34, calendar}, options);
const meiji5 = Temporal.PlainDateTime.from({ era: "meiji", eraYear: 5, monthCode: "M01", day: 15, hour: 12, minute: 34, calendar }, options);
const meiji45 = Temporal.PlainDateTime.from({ era: "meiji", eraYear: 45, monthCode: "M05", day: 19, hour: 12, minute: 34, calendar }, options);
const taisho1 = Temporal.PlainDateTime.from({ era: "taisho", eraYear: 1, monthCode: "M08", day: 9, hour: 12, minute: 34, calendar }, options);
const taisho6 = Temporal.PlainDateTime.from({ era: "taisho", eraYear: 6, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const taisho15 = Temporal.PlainDateTime.from({ era: "taisho", eraYear: 15, monthCode: "M05", day: 20, hour: 12, minute: 34, calendar }, options);
const showa1 = Temporal.PlainDateTime.from({ era: "showa", eraYear: 1, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }, options);
const showa55 = Temporal.PlainDateTime.from({ era: "showa", eraYear: 55, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const showa64 = Temporal.PlainDateTime.from({ era: "showa", eraYear: 64, monthCode: "M01", day: 3, hour: 12, minute: 34, calendar }, options);
const heisei1 = Temporal.PlainDateTime.from({ era: "heisei", eraYear: 1, monthCode: "M02", day: 27, hour: 12, minute: 34, calendar }, options);
const heisei30 = Temporal.PlainDateTime.from({ era: "heisei", eraYear: 30, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const heisei31 = Temporal.PlainDateTime.from({ era: "heisei", eraYear: 31, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options);
const reiwa1 = Temporal.PlainDateTime.from({ era: "reiwa", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options);
const reiwa2 = Temporal.PlainDateTime.from({ era: "reiwa", eraYear: 2, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const tests = [
// From Heisei 30 (2018) to Reiwa 2 (2020) - crossing era boundary
[
heisei30, reiwa2,
[-2, 0, 0, 0, "-2y backwards from Heisei 30 March to Reiwa 2 March"],
[0, -24, 0, 0, "-24mo backwards from Heisei 30 March to Reiwa 2 March"],
],
[
reiwa2, heisei30,
[2, 0, 0, 0, "2y from Heisei 30 March to Reiwa 2 March"],
[0, 24, 0, 0, "24mo from Heisei 30 March to Reiwa 2 March"],
],
// Within same year but different eras
[
heisei31, reiwa1,
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
],
[
reiwa1, heisei31,
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
],
// From Showa 55 (1980) to Heisei 30 (2018) - crossing era boundary
[
showa55, heisei30,
[-38, 0, 0, 0, "-38y backwards from Showa 55 March to Heisei 30 March"],
[0, -456, 0, 0, "-456mo backwards from Showa 55 March to Heisei 30 March"],
],
[
heisei30, showa55,
[38, 0, 0, 0, "38y from Showa 55 March to Heisei 30 March"],
[0, 456, 0, 0, "456mo from Showa 55 March to Heisei 30 March"],
],
// Within same year but different eras
[
showa64, heisei1,
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
],
[
heisei1, showa64,
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
],
// From Taisho 6 (1917) to Showa 55 (1980) - crossing era boundary
[
taisho6, showa55,
[-63, 0, 0, 0, "-63y backwards from Taisho 6 March to Showa 55 March"],
[0, -756, 0, 0, "-756mo backwards from Taisho 6 March to Showa 55 March"],
],
[
showa55, taisho6,
[63, 0, 0, 0, "63y from Taisho 6 March to Showa 55 March"],
[0, 756, 0, 0, "756mo from Taisho 6 March to Showa 55 March"],
],
// Within same year but different eras
[
taisho15, showa1,
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
],
[
showa1, taisho15,
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
],
// From Meiji 5 (1872) to Taisho 6 (1917) - crossing era boundary
// Note that contemporarily January 15 1872 would have been Meiji 4 in the
// pre-1873 lunisolar calendar, but the spec-mandated behaviour is proleptic
[
meiji5, taisho6,
[-45, -2, 0, 0, "-45y -2mo backwards from Meiji 5 January to Taisho 6 March"],
[0, -542, 0, 0, "-542mo backwards from Meiji 5 January to Taisho 6 March"],
],
[
taisho6, meiji5,
[45, 2, 0, 0, "45y 2mo from Meiji 5 January to Taisho 6 March"],
[0, 542, 0, 0, "542mo from Meiji 5 January to Taisho 6 March"],
],
// Within same year but different eras
[
meiji45, taisho1,
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
],
[
taisho1, meiji45,
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
],
// Last pre-Meiji day to first day of Meiji era
[
ce1868, meiji1,
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
],
[
meiji1, ce1868,
[0, 0, 0, 1, "from day before Meiji era to first day"],
[0, 0, 0, 1, "from day before Meiji era to first day"],
],
// CE-BCE boundary
[
bce1, ce1,
[-1, 0, 0, 0, "-1y backwards from 1 BCE to 1 CE"],
[0, -12, 0, 0, "-12mo backwards from 1 BCE to 1 CE"],
],
[
ce1, bce1,
[1, 0, 0, 0, "1y from 1 BCE to 1 CE"],
[0, 12, 0, 0, "12mo from 1 BCE to 1 CE"],
],
];
for (const [one, two, yearsTest, monthsTest] of tests) {
let [years, months, weeks, days, descr] = yearsTest;
let result = one.since(two, { largestUnit: "years" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
[years, months, weeks, days, descr] = monthsTest;
result = one.since(two, { largestUnit: "months" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
const oneISO = one.withCalendar("iso8601");
const twoISO = two.withCalendar("iso8601");
const resultWeeks = one.since(two, { largestUnit: "weeks" });
const resultWeeksISO = oneISO.since(twoISO, { largestUnit: "weeks" });
TemporalHelpers.assertDurationsEqual(resultWeeks, resultWeeksISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit weeks`);
const resultDays = one.since(two);
const resultDaysISO = oneISO.since(twoISO);
TemporalHelpers.assertDurationsEqual(resultDays, resultDaysISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit days`);
}

View File

@ -0,0 +1,169 @@
// Copyright (C) 2025 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.until
description: Date difference works correctly across era boundaries
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "japanese";
const options = { overflow: "reject" };
const bce1 = Temporal.PlainDateTime.from({ era: "bce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options);
const ce1 = Temporal.PlainDateTime.from({ era: "ce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options);
const ce1868 = Temporal.PlainDateTime.from({ era: "ce", eraYear: 1868, monthCode: "M10", day: 22, hour: 12, minute: 34, calendar }, options);
const meiji1 = Temporal.PlainDateTime.from({ era: "meiji", eraYear: 1, monthCode: "M10", day: 23, hour: 12, minute: 34, calendar}, options);
const meiji5 = Temporal.PlainDateTime.from({ era: "meiji", eraYear: 5, monthCode: "M01", day: 15, hour: 12, minute: 34, calendar }, options);
const meiji45 = Temporal.PlainDateTime.from({ era: "meiji", eraYear: 45, monthCode: "M05", day: 19, hour: 12, minute: 34, calendar }, options);
const taisho1 = Temporal.PlainDateTime.from({ era: "taisho", eraYear: 1, monthCode: "M08", day: 9, hour: 12, minute: 34, calendar }, options);
const taisho6 = Temporal.PlainDateTime.from({ era: "taisho", eraYear: 6, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const taisho15 = Temporal.PlainDateTime.from({ era: "taisho", eraYear: 15, monthCode: "M05", day: 20, hour: 12, minute: 34, calendar }, options);
const showa1 = Temporal.PlainDateTime.from({ era: "showa", eraYear: 1, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }, options);
const showa55 = Temporal.PlainDateTime.from({ era: "showa", eraYear: 55, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const showa64 = Temporal.PlainDateTime.from({ era: "showa", eraYear: 64, monthCode: "M01", day: 3, hour: 12, minute: 34, calendar }, options);
const heisei1 = Temporal.PlainDateTime.from({ era: "heisei", eraYear: 1, monthCode: "M02", day: 27, hour: 12, minute: 34, calendar }, options);
const heisei30 = Temporal.PlainDateTime.from({ era: "heisei", eraYear: 30, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const heisei31 = Temporal.PlainDateTime.from({ era: "heisei", eraYear: 31, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options);
const reiwa1 = Temporal.PlainDateTime.from({ era: "reiwa", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options);
const reiwa2 = Temporal.PlainDateTime.from({ era: "reiwa", eraYear: 2, monthCode: "M03", day: 15, hour: 12, minute: 34, calendar }, options);
const tests = [
// From Heisei 30 (2018) to Reiwa 2 (2020) - crossing era boundary
[
heisei30, reiwa2,
[2, 0, 0, 0, "2y from Heisei 30 March to Reiwa 2 March"],
[0, 24, 0, 0, "24mo from Heisei 30 March to Reiwa 2 March"],
],
[
reiwa2, heisei30,
[-2, 0, 0, 0, "-2y backwards from Heisei 30 March to Reiwa 2 March"],
[0, -24, 0, 0, "-24mo backwards from Heisei 30 March to Reiwa 2 March"],
],
// Within same year but different eras
[
heisei31, reiwa1,
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
],
[
reiwa1, heisei31,
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
],
// From Showa 55 (1980) to Heisei 30 (2018) - crossing era boundary
[
showa55, heisei30,
[38, 0, 0, 0, "38y from Showa 55 March to Heisei 30 March"],
[0, 456, 0, 0, "456mo from Showa 55 March to Heisei 30 March"],
],
[
heisei30, showa55,
[-38, 0, 0, 0, "-38y backwards from Showa 55 March to Heisei 30 March"],
[0, -456, 0, 0, "-456mo backwards from Showa 55 March to Heisei 30 March"],
],
// Within same year but different eras
[
showa64, heisei1,
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
],
[
heisei1, showa64,
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
],
// From Taisho 6 (1917) to Showa 55 (1980) - crossing era boundary
[
taisho6, showa55,
[63, 0, 0, 0, "63y from Taisho 6 March to Showa 55 March"],
[0, 756, 0, 0, "756mo from Taisho 6 March to Showa 55 March"],
],
[
showa55, taisho6,
[-63, 0, 0, 0, "-63y backwards from Taisho 6 March to Showa 55 March"],
[0, -756, 0, 0, "-756mo backwards from Taisho 6 March to Showa 55 March"],
],
// Within same year but different eras
[
taisho15, showa1,
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
],
[
showa1, taisho15,
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
],
// From Meiji 5 (1872) to Taisho 6 (1917) - crossing era boundary
// Note that contemporarily January 15 1872 would have been Meiji 4 in the
// pre-1873 lunisolar calendar, but the spec-mandated behaviour is proleptic
[
meiji5, taisho6,
[45, 2, 0, 0, "45y 2mo from Meiji 5 January to Taisho 6 March"],
[0, 542, 0, 0, "542mo from Meiji 5 January to Taisho 6 March"],
],
[
taisho6, meiji5,
[-45, -2, 0, 0, "-45y -2mo backwards from Meiji 5 January to Taisho 6 March"],
[0, -542, 0, 0, "-542mo backwards from Meiji 5 January to Taisho 6 March"],
],
// Within same year but different eras
[
meiji45, taisho1,
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
],
[
taisho1, meiji45,
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
],
// Last pre-Meiji day to first day of Meiji era
[
ce1868, meiji1,
[0, 0, 0, 1, "from day before Meiji era to first day"],
[0, 0, 0, 1, "from day before Meiji era to first day"],
],
[
meiji1, ce1868,
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
],
// CE-BCE boundary
[
bce1, ce1,
[1, 0, 0, 0, "1y from 1 BCE to 1 CE"],
[0, 12, 0, 0, "12mo from 1 BCE to 1 CE"],
],
[
ce1, bce1,
[-1, 0, 0, 0, "-1y backwards from 1 BCE to 1 CE"],
[0, -12, 0, 0, "-12mo backwards from 1 BCE to 1 CE"],
],
];
for (const [one, two, yearsTest, monthsTest] of tests) {
let [years, months, weeks, days, descr] = yearsTest;
let result = one.until(two, { largestUnit: "years" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
[years, months, weeks, days, descr] = monthsTest;
result = one.until(two, { largestUnit: "months" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
const oneISO = one.withCalendar("iso8601");
const twoISO = two.withCalendar("iso8601");
const resultWeeks = one.until(two, { largestUnit: "weeks" });
const resultWeeksISO = oneISO.until(twoISO, { largestUnit: "weeks" });
TemporalHelpers.assertDurationsEqual(resultWeeks, resultWeeksISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit weeks`);
const resultDays = one.until(two);
const resultDaysISO = oneISO.until(twoISO);
TemporalHelpers.assertDurationsEqual(resultDays, resultDaysISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit days`);
}

View File

@ -0,0 +1,169 @@
// Copyright (C) 2025 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.since
description: Date difference works correctly across era boundaries
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "japanese";
const options = { overflow: "reject" };
const bce1 = Temporal.ZonedDateTime.from({ era: "bce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const ce1 = Temporal.ZonedDateTime.from({ era: "ce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const ce1868 = Temporal.ZonedDateTime.from({ era: "ce", eraYear: 1868, monthCode: "M10", day: 22, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const meiji1 = Temporal.ZonedDateTime.from({ era: "meiji", eraYear: 1, monthCode: "M10", day: 23, hour: 12, minute: 34, timeZone: "UTC", calendar}, options);
const meiji5 = Temporal.ZonedDateTime.from({ era: "meiji", eraYear: 5, monthCode: "M01", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const meiji45 = Temporal.ZonedDateTime.from({ era: "meiji", eraYear: 45, monthCode: "M05", day: 19, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const taisho1 = Temporal.ZonedDateTime.from({ era: "taisho", eraYear: 1, monthCode: "M08", day: 9, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const taisho6 = Temporal.ZonedDateTime.from({ era: "taisho", eraYear: 6, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const taisho15 = Temporal.ZonedDateTime.from({ era: "taisho", eraYear: 15, monthCode: "M05", day: 20, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const showa1 = Temporal.ZonedDateTime.from({ era: "showa", eraYear: 1, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const showa55 = Temporal.ZonedDateTime.from({ era: "showa", eraYear: 55, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const showa64 = Temporal.ZonedDateTime.from({ era: "showa", eraYear: 64, monthCode: "M01", day: 3, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const heisei1 = Temporal.ZonedDateTime.from({ era: "heisei", eraYear: 1, monthCode: "M02", day: 27, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const heisei30 = Temporal.ZonedDateTime.from({ era: "heisei", eraYear: 30, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const heisei31 = Temporal.ZonedDateTime.from({ era: "heisei", eraYear: 31, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const reiwa1 = Temporal.ZonedDateTime.from({ era: "reiwa", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const reiwa2 = Temporal.ZonedDateTime.from({ era: "reiwa", eraYear: 2, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const tests = [
// From Heisei 30 (2018) to Reiwa 2 (2020) - crossing era boundary
[
heisei30, reiwa2,
[-2, 0, 0, 0, "-2y backwards from Heisei 30 March to Reiwa 2 March"],
[0, -24, 0, 0, "-24mo backwards from Heisei 30 March to Reiwa 2 March"],
],
[
reiwa2, heisei30,
[2, 0, 0, 0, "2y from Heisei 30 March to Reiwa 2 March"],
[0, 24, 0, 0, "24mo from Heisei 30 March to Reiwa 2 March"],
],
// Within same year but different eras
[
heisei31, reiwa1,
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
],
[
reiwa1, heisei31,
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
],
// From Showa 55 (1980) to Heisei 30 (2018) - crossing era boundary
[
showa55, heisei30,
[-38, 0, 0, 0, "-38y backwards from Showa 55 March to Heisei 30 March"],
[0, -456, 0, 0, "-456mo backwards from Showa 55 March to Heisei 30 March"],
],
[
heisei30, showa55,
[38, 0, 0, 0, "38y from Showa 55 March to Heisei 30 March"],
[0, 456, 0, 0, "456mo from Showa 55 March to Heisei 30 March"],
],
// Within same year but different eras
[
showa64, heisei1,
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
],
[
heisei1, showa64,
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
],
// From Taisho 6 (1917) to Showa 55 (1980) - crossing era boundary
[
taisho6, showa55,
[-63, 0, 0, 0, "-63y backwards from Taisho 6 March to Showa 55 March"],
[0, -756, 0, 0, "-756mo backwards from Taisho 6 March to Showa 55 March"],
],
[
showa55, taisho6,
[63, 0, 0, 0, "63y from Taisho 6 March to Showa 55 March"],
[0, 756, 0, 0, "756mo from Taisho 6 March to Showa 55 March"],
],
// Within same year but different eras
[
taisho15, showa1,
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
],
[
showa1, taisho15,
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
],
// From Meiji 5 (1872) to Taisho 6 (1917) - crossing era boundary
// Note that contemporarily January 15 1872 would have been Meiji 4 in the
// pre-1873 lunisolar calendar, but the spec-mandated behaviour is proleptic
[
meiji5, taisho6,
[-45, -2, 0, 0, "-45y -2mo backwards from Meiji 5 January to Taisho 6 March"],
[0, -542, 0, 0, "-542mo backwards from Meiji 5 January to Taisho 6 March"],
],
[
taisho6, meiji5,
[45, 2, 0, 0, "45y 2mo from Meiji 5 January to Taisho 6 March"],
[0, 542, 0, 0, "542mo from Meiji 5 January to Taisho 6 March"],
],
// Within same year but different eras
[
meiji45, taisho1,
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
],
[
taisho1, meiji45,
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
],
// Last pre-Meiji day to first day of Meiji era
[
ce1868, meiji1,
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
],
[
meiji1, ce1868,
[0, 0, 0, 1, "from day before Meiji era to first day"],
[0, 0, 0, 1, "from day before Meiji era to first day"],
],
// CE-BCE boundary
[
bce1, ce1,
[-1, 0, 0, 0, "-1y backwards from 1 BCE to 1 CE"],
[0, -12, 0, 0, "-12mo backwards from 1 BCE to 1 CE"],
],
[
ce1, bce1,
[1, 0, 0, 0, "1y from 1 BCE to 1 CE"],
[0, 12, 0, 0, "12mo from 1 BCE to 1 CE"],
],
];
for (const [one, two, yearsTest, monthsTest] of tests) {
let [years, months, weeks, days, descr] = yearsTest;
let result = one.since(two, { largestUnit: "years" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
[years, months, weeks, days, descr] = monthsTest;
result = one.since(two, { largestUnit: "months" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
const oneISO = one.withCalendar("iso8601");
const twoISO = two.withCalendar("iso8601");
const resultWeeks = one.since(two, { largestUnit: "weeks" });
const resultWeeksISO = oneISO.since(twoISO, { largestUnit: "weeks" });
TemporalHelpers.assertDurationsEqual(resultWeeks, resultWeeksISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit weeks`);
const resultDays = one.since(two);
const resultDaysISO = oneISO.since(twoISO);
TemporalHelpers.assertDurationsEqual(resultDays, resultDaysISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit days`);
}

View File

@ -0,0 +1,169 @@
// Copyright (C) 2025 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.until
description: Date difference works correctly across era boundaries
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "japanese";
const options = { overflow: "reject" };
const bce1 = Temporal.ZonedDateTime.from({ era: "bce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const ce1 = Temporal.ZonedDateTime.from({ era: "ce", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const ce1868 = Temporal.ZonedDateTime.from({ era: "ce", eraYear: 1868, monthCode: "M10", day: 22, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const meiji1 = Temporal.ZonedDateTime.from({ era: "meiji", eraYear: 1, monthCode: "M10", day: 23, hour: 12, minute: 34, timeZone: "UTC", calendar}, options);
const meiji5 = Temporal.ZonedDateTime.from({ era: "meiji", eraYear: 5, monthCode: "M01", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const meiji45 = Temporal.ZonedDateTime.from({ era: "meiji", eraYear: 45, monthCode: "M05", day: 19, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const taisho1 = Temporal.ZonedDateTime.from({ era: "taisho", eraYear: 1, monthCode: "M08", day: 9, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const taisho6 = Temporal.ZonedDateTime.from({ era: "taisho", eraYear: 6, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const taisho15 = Temporal.ZonedDateTime.from({ era: "taisho", eraYear: 15, monthCode: "M05", day: 20, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const showa1 = Temporal.ZonedDateTime.from({ era: "showa", eraYear: 1, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const showa55 = Temporal.ZonedDateTime.from({ era: "showa", eraYear: 55, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const showa64 = Temporal.ZonedDateTime.from({ era: "showa", eraYear: 64, monthCode: "M01", day: 3, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const heisei1 = Temporal.ZonedDateTime.from({ era: "heisei", eraYear: 1, monthCode: "M02", day: 27, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const heisei30 = Temporal.ZonedDateTime.from({ era: "heisei", eraYear: 30, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const heisei31 = Temporal.ZonedDateTime.from({ era: "heisei", eraYear: 31, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const reiwa1 = Temporal.ZonedDateTime.from({ era: "reiwa", eraYear: 1, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const reiwa2 = Temporal.ZonedDateTime.from({ era: "reiwa", eraYear: 2, monthCode: "M03", day: 15, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const tests = [
// From Heisei 30 (2018) to Reiwa 2 (2020) - crossing era boundary
[
heisei30, reiwa2,
[2, 0, 0, 0, "2y from Heisei 30 March to Reiwa 2 March"],
[0, 24, 0, 0, "24mo from Heisei 30 March to Reiwa 2 March"],
],
[
reiwa2, heisei30,
[-2, 0, 0, 0, "-2y backwards from Heisei 30 March to Reiwa 2 March"],
[0, -24, 0, 0, "-24mo backwards from Heisei 30 March to Reiwa 2 March"],
],
// Within same year but different eras
[
heisei31, reiwa1,
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
[0, 2, 0, 0, "2mo from Heisei 31 April to Reiwa 1 June"],
],
[
reiwa1, heisei31,
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
[0, -2, 0, 0, "-2mo backwards from Heisei 31 April to Reiwa 1 June"],
],
// From Showa 55 (1980) to Heisei 30 (2018) - crossing era boundary
[
showa55, heisei30,
[38, 0, 0, 0, "38y from Showa 55 March to Heisei 30 March"],
[0, 456, 0, 0, "456mo from Showa 55 March to Heisei 30 March"],
],
[
heisei30, showa55,
[-38, 0, 0, 0, "-38y backwards from Showa 55 March to Heisei 30 March"],
[0, -456, 0, 0, "-456mo backwards from Showa 55 March to Heisei 30 March"],
],
// Within same year but different eras
[
showa64, heisei1,
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, 1, 0, 24, "1mo 24d from Showa 64 January 3 to Heisei 1 February 27"],
],
[
heisei1, showa64,
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
[0, -1, 0, -24, "-1mo -24d from Showa 64 January 3 to Heisei 1 February 27"],
],
// From Taisho 6 (1917) to Showa 55 (1980) - crossing era boundary
[
taisho6, showa55,
[63, 0, 0, 0, "63y from Taisho 6 March to Showa 55 March"],
[0, 756, 0, 0, "756mo from Taisho 6 March to Showa 55 March"],
],
[
showa55, taisho6,
[-63, 0, 0, 0, "-63y backwards from Taisho 6 March to Showa 55 March"],
[0, -756, 0, 0, "-756mo backwards from Taisho 6 March to Showa 55 March"],
],
// Within same year but different eras
[
taisho15, showa1,
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
[0, 7, 0, 10, "7mo 10d from Taisho 15 July 20 to Showa 1 December 30"],
],
[
showa1, taisho15,
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
[0, -7, 0, -10, "-7mo -10d backwards from Taisho 15 July 20 to Showa 1 December 30"],
],
// From Meiji 5 (1872) to Taisho 6 (1917) - crossing era boundary
// Note that contemporarily January 15 1872 would have been Meiji 4 in the
// pre-1873 lunisolar calendar, but the spec-mandated behaviour is proleptic
[
meiji5, taisho6,
[45, 2, 0, 0, "45y 2mo from Meiji 5 January to Taisho 6 March"],
[0, 542, 0, 0, "542mo from Meiji 5 January to Taisho 6 March"],
],
[
taisho6, meiji5,
[-45, -2, 0, 0, "-45y -2mo backwards from Meiji 5 January to Taisho 6 March"],
[0, -542, 0, 0, "-542mo backwards from Meiji 5 January to Taisho 6 March"],
],
// Within same year but different eras
[
meiji45, taisho1,
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
[0, 2, 0, 21, "2mo 21d from Meiji 45 May 19 to Taisho 1 August 9"],
],
[
taisho1, meiji45,
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
[0, -2, 0, -21, "-2mo -21d backwards from Meiji 45 May 19 to Taisho 1 August 9"],
],
// Last pre-Meiji day to first day of Meiji era
[
ce1868, meiji1,
[0, 0, 0, 1, "from day before Meiji era to first day"],
[0, 0, 0, 1, "from day before Meiji era to first day"],
],
[
meiji1, ce1868,
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
[0, 0, 0, -1, "backwards from day before Meiji era to first day"],
],
// CE-BCE boundary
[
bce1, ce1,
[1, 0, 0, 0, "1y from 1 BCE to 1 CE"],
[0, 12, 0, 0, "12mo from 1 BCE to 1 CE"],
],
[
ce1, bce1,
[-1, 0, 0, 0, "-1y backwards from 1 BCE to 1 CE"],
[0, -12, 0, 0, "-12mo backwards from 1 BCE to 1 CE"],
],
];
for (const [one, two, yearsTest, monthsTest] of tests) {
let [years, months, weeks, days, descr] = yearsTest;
let result = one.until(two, { largestUnit: "years" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
[years, months, weeks, days, descr] = monthsTest;
result = one.until(two, { largestUnit: "months" });
TemporalHelpers.assertDuration(result, years, months, weeks, days, 0, 0, 0, 0, 0, 0, descr);
const oneISO = one.withCalendar("iso8601");
const twoISO = two.withCalendar("iso8601");
const resultWeeks = one.until(two, { largestUnit: "weeks" });
const resultWeeksISO = oneISO.until(twoISO, { largestUnit: "weeks" });
TemporalHelpers.assertDurationsEqual(resultWeeks, resultWeeksISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit weeks`);
const resultDays = one.until(two);
const resultDaysISO = oneISO.until(twoISO);
TemporalHelpers.assertDurationsEqual(resultDays, resultDaysISO,
`${one.year}-${one.monthCode}-${one.day} : ${two.year}-${two.monthCode}-${two.day} largestUnit days`);
}