From 883d4ece0b32b7c9a00b95da8b83c4cfec21f574 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Mon, 10 Nov 2025 16:45:44 -0800 Subject: [PATCH] Expand current lunisolar leap months difference This takes the current 'until-across-lunisolar-leap-months.js' which didn't test much of anything too carefully, and expands it to cover comprehensive date difference arithmetic across and including leap months in the Chinese and Dangi calendars, for PlainDate, PlainDateTime, and ZonedDateTime. Hebrew calendar arithmetic will follow in a different PR. --- .../prototype/since/leap-months-chinese.js | 164 ++++++++++++++++++ .../prototype/since/leap-months-dangi.js | 164 ++++++++++++++++++ .../prototype/until/leap-months-chinese.js | 164 ++++++++++++++++++ .../prototype/until/leap-months-dangi.js | 164 ++++++++++++++++++ .../until-across-lunisolar-leap-months.js | 20 --- .../prototype/since/leap-months-chinese.js | 164 ++++++++++++++++++ .../prototype/since/leap-months-dangi.js | 164 ++++++++++++++++++ .../prototype/until/leap-months-chinese.js | 164 ++++++++++++++++++ .../prototype/until/leap-months-dangi.js | 164 ++++++++++++++++++ .../prototype/since/leap-months-chinese.js | 164 ++++++++++++++++++ .../prototype/since/leap-months-dangi.js | 164 ++++++++++++++++++ .../prototype/until/leap-months-chinese.js | 164 ++++++++++++++++++ .../prototype/until/leap-months-dangi.js | 164 ++++++++++++++++++ 13 files changed, 1968 insertions(+), 20 deletions(-) create mode 100644 test/intl402/Temporal/PlainDate/prototype/since/leap-months-chinese.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/since/leap-months-dangi.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/until/leap-months-chinese.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/until/leap-months-dangi.js delete mode 100644 test/intl402/Temporal/PlainDate/prototype/until/until-across-lunisolar-leap-months.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-chinese.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-dangi.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-chinese.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-dangi.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-chinese.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-dangi.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-chinese.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-dangi.js diff --git a/test/intl402/Temporal/PlainDate/prototype/since/leap-months-chinese.js b/test/intl402/Temporal/PlainDate/prototype/since/leap-months-chinese.js new file mode 100644 index 0000000000..f8d2911d78 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/since/leap-months-chinese.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in chinese calendar +esid: sec-temporal.plaindate.prototype.since +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDate.from({ year: 2000, monthCode: "M04", day: 1, calendar }, options); +const common1Month5 = Temporal.PlainDate.from({ year: 2000, monthCode: "M05", day: 1, calendar }, options); +const common1Month6 = Temporal.PlainDate.from({ year: 2000, monthCode: "M06", day: 1, calendar }, options); +const leapMonth4 = Temporal.PlainDate.from({ year: 2001, monthCode: "M04", day: 1, calendar }, options); +const leapMonth4L = Temporal.PlainDate.from({ year: 2001, monthCode: "M04L", day: 1, calendar }, options); +const leapMonth5 = Temporal.PlainDate.from({ year: 2001, monthCode: "M05", day: 1, calendar }, options); +const common2Month4 = Temporal.PlainDate.from({ year: 2002, monthCode: "M04", day: 1, calendar }, options); +const common2Month5 = Temporal.PlainDate.from({ year: 2002, monthCode: "M05", day: 1, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -12, 0, 0, "M04-M04 common-leap backwards is -12mo"], + ], + [ + leapMonth4, common2Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -13, 0, 0, "M04-M04 leap-common backwards is -13mo not -12mo"], + ], + [ + common1Month4, common2Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -13, 0, 0, "M05-M05 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth5, common2Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -12, 0, 0, "M05-M05 leap-common backwards is -12mo"], + ], + [ + common1Month5, common2Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month4, leapMonth4L, + [-1, -1, 0, 0, "M04-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M04-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, -12, 0, 0, "M04L-M04 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M04 backwards is -12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, -12, 0, 0, "M05-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M05-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common2Month5, + [-1, -1, 0, 0, "M04L-M05 backwards is -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M05 backwards is -13mo"], + ], + [ + common1Month6, leapMonth5, + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 13, 0, 0, "M04-M04 common-leap is 13mo not 12mo"], + ], + [ + leapMonth4, common1Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 12, 0, 0, "M04-M04 leap-common is 12mo not 13mo"], + ], + [ + common2Month4, common1Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common2Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 12, 0, 0, "M05-M05 common-leap is 12mo not 13mo"], + ], + [ + leapMonth5, common1Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 13, 0, 0, "M05-M05 leap-common is 13mo not 12mo"], + ], + [ + common2Month5, common1Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, 12, 0, 0, "M04-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M04-M04L is 12mo"], + ], + [ + leapMonth4L, common1Month4, + [1, 0, 0, 0, "M04L-M04 is 1y not 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M04 is 13mo"], + ], + [ + common2Month5, leapMonth4L, + [1, 1, 0, 0, "M05-M04L is 1y 1mo"], + [0, 13, 0, 0, "M05-M04L is 13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, 12, 0, 0, "M04L-M05 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M05 is 12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/since/leap-months-dangi.js b/test/intl402/Temporal/PlainDate/prototype/since/leap-months-dangi.js new file mode 100644 index 0000000000..1bcd845c8f --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/since/leap-months-dangi.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in dangi calendar +esid: sec-temporal.plaindate.prototype.since +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDate.from({ year: 2000, monthCode: "M04", day: 1, calendar }, options); +const common1Month5 = Temporal.PlainDate.from({ year: 2000, monthCode: "M05", day: 1, calendar }, options); +const common1Month6 = Temporal.PlainDate.from({ year: 2000, monthCode: "M06", day: 1, calendar }, options); +const leapMonth4 = Temporal.PlainDate.from({ year: 2001, monthCode: "M04", day: 1, calendar }, options); +const leapMonth4L = Temporal.PlainDate.from({ year: 2001, monthCode: "M04L", day: 1, calendar }, options); +const leapMonth5 = Temporal.PlainDate.from({ year: 2001, monthCode: "M05", day: 1, calendar }, options); +const common2Month4 = Temporal.PlainDate.from({ year: 2002, monthCode: "M04", day: 1, calendar }, options); +const common2Month5 = Temporal.PlainDate.from({ year: 2002, monthCode: "M05", day: 1, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -12, 0, 0, "M04-M04 common-leap backwards is -12mo"], + ], + [ + leapMonth4, common2Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -13, 0, 0, "M04-M04 leap-common backwards is -13mo not -12mo"], + ], + [ + common1Month4, common2Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -13, 0, 0, "M05-M05 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth5, common2Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -12, 0, 0, "M05-M05 leap-common backwards is -12mo"], + ], + [ + common1Month5, common2Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month4, leapMonth4L, + [-1, -1, 0, 0, "M04-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M04-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, -12, 0, 0, "M04L-M04 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M04 backwards is -12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, -12, 0, 0, "M05-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M05-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common2Month5, + [-1, -1, 0, 0, "M04L-M05 backwards is -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M05 backwards is -13mo"], + ], + [ + common1Month6, leapMonth5, + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 13, 0, 0, "M04-M04 common-leap is 13mo not 12mo"], + ], + [ + leapMonth4, common1Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 12, 0, 0, "M04-M04 leap-common is 12mo not 13mo"], + ], + [ + common2Month4, common1Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common2Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 12, 0, 0, "M05-M05 common-leap is 12mo not 13mo"], + ], + [ + leapMonth5, common1Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 13, 0, 0, "M05-M05 leap-common is 13mo not 12mo"], + ], + [ + common2Month5, common1Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, 12, 0, 0, "M04-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M04-M04L is 12mo"], + ], + [ + leapMonth4L, common1Month4, + [1, 0, 0, 0, "M04L-M04 is 1y not 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M04 is 13mo"], + ], + [ + common2Month5, leapMonth4L, + [1, 1, 0, 0, "M05-M04L is 1y 1mo"], + [0, 13, 0, 0, "M05-M04L is 13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, 12, 0, 0, "M04L-M05 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M05 is 12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/until/leap-months-chinese.js b/test/intl402/Temporal/PlainDate/prototype/until/leap-months-chinese.js new file mode 100644 index 0000000000..2838d3b576 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/until/leap-months-chinese.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in chinese calendar +esid: sec-temporal.plaindate.prototype.until +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDate.from({ year: 2000, monthCode: "M04", day: 1, calendar }, options); +const common1Month5 = Temporal.PlainDate.from({ year: 2000, monthCode: "M05", day: 1, calendar }, options); +const common1Month6 = Temporal.PlainDate.from({ year: 2000, monthCode: "M06", day: 1, calendar }, options); +const leapMonth4 = Temporal.PlainDate.from({ year: 2001, monthCode: "M04", day: 1, calendar }, options); +const leapMonth4L = Temporal.PlainDate.from({ year: 2001, monthCode: "M04L", day: 1, calendar }, options); +const leapMonth5 = Temporal.PlainDate.from({ year: 2001, monthCode: "M05", day: 1, calendar }, options); +const common2Month4 = Temporal.PlainDate.from({ year: 2002, monthCode: "M04", day: 1, calendar }, options); +const common2Month5 = Temporal.PlainDate.from({ year: 2002, monthCode: "M05", day: 1, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 12, 0, 0, "M04-M04 common-leap is 12mo"], + ], + [ + leapMonth4, common2Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 13, 0, 0, "M04-M04 leap-common is 13mo not 12mo"], + ], + [ + common1Month4, common2Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common1Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 13, 0, 0, "M05-M05 common-leap is 13mo not 12mo"], + ], + [ + leapMonth5, common2Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 12, 0, 0, "M05-M05 leap-common is 12mo"], + ], + [ + common1Month5, common2Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common1Month4, leapMonth4L, + [1, 1, 0, 0, "M04-M04L is 1y 1mo"], + [0, 13, 0, 0, "M04-M04L is 13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, 12, 0, 0, "M04L-M04 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M04 is 12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, 12, 0, 0, "M05-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M05-M04L is 12mo"], + ], + [ + leapMonth4L, common2Month5, + [1, 1, 0, 0, "M04L-M05 is 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M05 is 13mo"], + ], + [ + common1Month6, leapMonth5, + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -13, 0, 0, "M04-M04 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth4, common1Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -12, 0, 0, "M04-M04 leap-common backwards is -12mo not -13mo"], + ], + [ + common2Month4, common1Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -12, 0, 0, "M05-M05 common-leap backwards is -12mo not -13mo"], + ], + [ + leapMonth5, common1Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -13, 0, 0, "M05-M05 leap-common backwards is -13mo not -12mo"], + ], + [ + common2Month5, common1Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, -12, 0, 0, "M04-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common1Month4, + [-1, 0, 0, 0, "M04L-M04 backwards is -1y not -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M04 backwards is -13mo"], + ], + [ + common2Month5, leapMonth4L, + [-1, -1, 0, 0, "M05-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M05-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, -12, 0, 0, "M04L-M05 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M05 backwards is -12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/until/leap-months-dangi.js b/test/intl402/Temporal/PlainDate/prototype/until/leap-months-dangi.js new file mode 100644 index 0000000000..60722e0f35 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/until/leap-months-dangi.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in dangi calendar +esid: sec-temporal.plaindate.prototype.until +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDate.from({ year: 2000, monthCode: "M04", day: 1, calendar }, options); +const common1Month5 = Temporal.PlainDate.from({ year: 2000, monthCode: "M05", day: 1, calendar }, options); +const common1Month6 = Temporal.PlainDate.from({ year: 2000, monthCode: "M06", day: 1, calendar }, options); +const leapMonth4 = Temporal.PlainDate.from({ year: 2001, monthCode: "M04", day: 1, calendar }, options); +const leapMonth4L = Temporal.PlainDate.from({ year: 2001, monthCode: "M04L", day: 1, calendar }, options); +const leapMonth5 = Temporal.PlainDate.from({ year: 2001, monthCode: "M05", day: 1, calendar }, options); +const common2Month4 = Temporal.PlainDate.from({ year: 2002, monthCode: "M04", day: 1, calendar }, options); +const common2Month5 = Temporal.PlainDate.from({ year: 2002, monthCode: "M05", day: 1, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 12, 0, 0, "M04-M04 common-leap is 12mo"], + ], + [ + leapMonth4, common2Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 13, 0, 0, "M04-M04 leap-common is 13mo not 12mo"], + ], + [ + common1Month4, common2Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common1Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 13, 0, 0, "M05-M05 common-leap is 13mo not 12mo"], + ], + [ + leapMonth5, common2Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 12, 0, 0, "M05-M05 leap-common is 12mo"], + ], + [ + common1Month5, common2Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common1Month4, leapMonth4L, + [1, 1, 0, 0, "M04-M04L is 1y 1mo"], + [0, 13, 0, 0, "M04-M04L is 13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, 12, 0, 0, "M04L-M04 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M04 is 12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, 12, 0, 0, "M05-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M05-M04L is 12mo"], + ], + [ + leapMonth4L, common2Month5, + [1, 1, 0, 0, "M04L-M05 is 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M05 is 13mo"], + ], + [ + common1Month6, leapMonth5, + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -13, 0, 0, "M04-M04 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth4, common1Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -12, 0, 0, "M04-M04 leap-common backwards is -12mo not -13mo"], + ], + [ + common2Month4, common1Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -12, 0, 0, "M05-M05 common-leap backwards is -12mo not -13mo"], + ], + [ + leapMonth5, common1Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -13, 0, 0, "M05-M05 leap-common backwards is -13mo not -12mo"], + ], + [ + common2Month5, common1Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, -12, 0, 0, "M04-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common1Month4, + [-1, 0, 0, 0, "M04L-M04 backwards is -1y not -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M04 backwards is -13mo"], + ], + [ + common2Month5, leapMonth4L, + [-1, -1, 0, 0, "M05-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M05-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, -12, 0, 0, "M04L-M05 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M05 backwards is -12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/until/until-across-lunisolar-leap-months.js b/test/intl402/Temporal/PlainDate/prototype/until/until-across-lunisolar-leap-months.js deleted file mode 100644 index 10842ffcd2..0000000000 --- a/test/intl402/Temporal/PlainDate/prototype/until/until-across-lunisolar-leap-months.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: dateUntil works as expected after a leap month in a lunisolar calendar -esid: sec-temporal.plaindate.prototype.until -features: [Temporal, Intl.Era-monthcode] ----*/ - -// 2001 is a leap year in the Chinese calendar with a M04L leap month. -// Therefore, month: 6 is M05 in 2001 but M06 in 2000 which is not a leap year. -const one = Temporal.PlainDate.from({ year: 2000, month: 6, day: 1, calendar: 'chinese' }); -const two = Temporal.PlainDate.from({ year: 2001, month: 6, day: 1, calendar: 'chinese' }); - -const expected = { years: 'P12M', months: 'P12M', weeks: 'P50W4D', days: 'P354D' }; - -Object.entries(expected).forEach(([largestUnit, expectedResult]) => { - const actualResult = one.until(two, { largestUnit }); - assert.sameValue(actualResult.toString(), expectedResult); -}); diff --git a/test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-chinese.js b/test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-chinese.js new file mode 100644 index 0000000000..901ebe2dd7 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-chinese.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in chinese calendar +esid: sec-temporal.plaindatetime.prototype.since +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month5 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month6 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4L = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth5 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month4 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month5 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -12, 0, 0, "M04-M04 common-leap backwards is -12mo"], + ], + [ + leapMonth4, common2Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -13, 0, 0, "M04-M04 leap-common backwards is -13mo not -12mo"], + ], + [ + common1Month4, common2Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -13, 0, 0, "M05-M05 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth5, common2Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -12, 0, 0, "M05-M05 leap-common backwards is -12mo"], + ], + [ + common1Month5, common2Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month4, leapMonth4L, + [-1, -1, 0, 0, "M04-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M04-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, -12, 0, 0, "M04L-M04 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M04 backwards is -12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, -12, 0, 0, "M05-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M05-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common2Month5, + [-1, -1, 0, 0, "M04L-M05 backwards is -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M05 backwards is -13mo"], + ], + [ + common1Month6, leapMonth5, + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 13, 0, 0, "M04-M04 common-leap is 13mo not 12mo"], + ], + [ + leapMonth4, common1Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 12, 0, 0, "M04-M04 leap-common is 12mo not 13mo"], + ], + [ + common2Month4, common1Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common2Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 12, 0, 0, "M05-M05 common-leap is 12mo not 13mo"], + ], + [ + leapMonth5, common1Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 13, 0, 0, "M05-M05 leap-common is 13mo not 12mo"], + ], + [ + common2Month5, common1Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, 12, 0, 0, "M04-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M04-M04L is 12mo"], + ], + [ + leapMonth4L, common1Month4, + [1, 0, 0, 0, "M04L-M04 is 1y not 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M04 is 13mo"], + ], + [ + common2Month5, leapMonth4L, + [1, 1, 0, 0, "M05-M04L is 1y 1mo"], + [0, 13, 0, 0, "M05-M04L is 13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, 12, 0, 0, "M04L-M05 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M05 is 12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-dangi.js b/test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-dangi.js new file mode 100644 index 0000000000..a29a57630e --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/since/leap-months-dangi.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in dangi calendar +esid: sec-temporal.plaindatetime.prototype.since +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month5 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month6 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4L = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth5 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month4 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month5 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -12, 0, 0, "M04-M04 common-leap backwards is -12mo"], + ], + [ + leapMonth4, common2Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -13, 0, 0, "M04-M04 leap-common backwards is -13mo not -12mo"], + ], + [ + common1Month4, common2Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -13, 0, 0, "M05-M05 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth5, common2Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -12, 0, 0, "M05-M05 leap-common backwards is -12mo"], + ], + [ + common1Month5, common2Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month4, leapMonth4L, + [-1, -1, 0, 0, "M04-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M04-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, -12, 0, 0, "M04L-M04 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M04 backwards is -12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, -12, 0, 0, "M05-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M05-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common2Month5, + [-1, -1, 0, 0, "M04L-M05 backwards is -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M05 backwards is -13mo"], + ], + [ + common1Month6, leapMonth5, + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 13, 0, 0, "M04-M04 common-leap is 13mo not 12mo"], + ], + [ + leapMonth4, common1Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 12, 0, 0, "M04-M04 leap-common is 12mo not 13mo"], + ], + [ + common2Month4, common1Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common2Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 12, 0, 0, "M05-M05 common-leap is 12mo not 13mo"], + ], + [ + leapMonth5, common1Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 13, 0, 0, "M05-M05 leap-common is 13mo not 12mo"], + ], + [ + common2Month5, common1Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, 12, 0, 0, "M04-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M04-M04L is 12mo"], + ], + [ + leapMonth4L, common1Month4, + [1, 0, 0, 0, "M04L-M04 is 1y not 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M04 is 13mo"], + ], + [ + common2Month5, leapMonth4L, + [1, 1, 0, 0, "M05-M04L is 1y 1mo"], + [0, 13, 0, 0, "M05-M04L is 13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, 12, 0, 0, "M04L-M05 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M05 is 12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-chinese.js b/test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-chinese.js new file mode 100644 index 0000000000..151b3aaf23 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-chinese.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in chinese calendar +esid: sec-temporal.plaindatetime.prototype.until +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month5 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month6 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4L = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth5 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month4 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month5 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 12, 0, 0, "M04-M04 common-leap is 12mo"], + ], + [ + leapMonth4, common2Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 13, 0, 0, "M04-M04 leap-common is 13mo not 12mo"], + ], + [ + common1Month4, common2Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common1Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 13, 0, 0, "M05-M05 common-leap is 13mo not 12mo"], + ], + [ + leapMonth5, common2Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 12, 0, 0, "M05-M05 leap-common is 12mo"], + ], + [ + common1Month5, common2Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common1Month4, leapMonth4L, + [1, 1, 0, 0, "M04-M04L is 1y 1mo"], + [0, 13, 0, 0, "M04-M04L is 13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, 12, 0, 0, "M04L-M04 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M04 is 12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, 12, 0, 0, "M05-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M05-M04L is 12mo"], + ], + [ + leapMonth4L, common2Month5, + [1, 1, 0, 0, "M04L-M05 is 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M05 is 13mo"], + ], + [ + common1Month6, leapMonth5, + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -13, 0, 0, "M04-M04 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth4, common1Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -12, 0, 0, "M04-M04 leap-common backwards is -12mo not -13mo"], + ], + [ + common2Month4, common1Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -12, 0, 0, "M05-M05 common-leap backwards is -12mo not -13mo"], + ], + [ + leapMonth5, common1Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -13, 0, 0, "M05-M05 leap-common backwards is -13mo not -12mo"], + ], + [ + common2Month5, common1Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, -12, 0, 0, "M04-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common1Month4, + [-1, 0, 0, 0, "M04L-M04 backwards is -1y not -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M04 backwards is -13mo"], + ], + [ + common2Month5, leapMonth4L, + [-1, -1, 0, 0, "M05-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M05-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, -12, 0, 0, "M04L-M05 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M05 backwards is -12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-dangi.js b/test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-dangi.js new file mode 100644 index 0000000000..8b2774e7a0 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/until/leap-months-dangi.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in dangi calendar +esid: sec-temporal.plaindatetime.prototype.until +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month5 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common1Month6 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth4L = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, calendar }, options); +const leapMonth5 = Temporal.PlainDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month4 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, calendar }, options); +const common2Month5 = Temporal.PlainDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 12, 0, 0, "M04-M04 common-leap is 12mo"], + ], + [ + leapMonth4, common2Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 13, 0, 0, "M04-M04 leap-common is 13mo not 12mo"], + ], + [ + common1Month4, common2Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common1Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 13, 0, 0, "M05-M05 common-leap is 13mo not 12mo"], + ], + [ + leapMonth5, common2Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 12, 0, 0, "M05-M05 leap-common is 12mo"], + ], + [ + common1Month5, common2Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common1Month4, leapMonth4L, + [1, 1, 0, 0, "M04-M04L is 1y 1mo"], + [0, 13, 0, 0, "M04-M04L is 13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, 12, 0, 0, "M04L-M04 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M04 is 12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, 12, 0, 0, "M05-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M05-M04L is 12mo"], + ], + [ + leapMonth4L, common2Month5, + [1, 1, 0, 0, "M04L-M05 is 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M05 is 13mo"], + ], + [ + common1Month6, leapMonth5, + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -13, 0, 0, "M04-M04 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth4, common1Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -12, 0, 0, "M04-M04 leap-common backwards is -12mo not -13mo"], + ], + [ + common2Month4, common1Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -12, 0, 0, "M05-M05 common-leap backwards is -12mo not -13mo"], + ], + [ + leapMonth5, common1Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -13, 0, 0, "M05-M05 leap-common backwards is -13mo not -12mo"], + ], + [ + common2Month5, common1Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, -12, 0, 0, "M04-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common1Month4, + [-1, 0, 0, 0, "M04L-M04 backwards is -1y not -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M04 backwards is -13mo"], + ], + [ + common2Month5, leapMonth4L, + [-1, -1, 0, 0, "M05-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M05-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, -12, 0, 0, "M04L-M05 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M05 backwards is -12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-chinese.js b/test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-chinese.js new file mode 100644 index 0000000000..2fd2e15351 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-chinese.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in chinese calendar +esid: sec-temporal.zoneddatetime.prototype.since +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month5 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month6 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4L = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth5 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month4 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month5 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -12, 0, 0, "M04-M04 common-leap backwards is -12mo"], + ], + [ + leapMonth4, common2Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -13, 0, 0, "M04-M04 leap-common backwards is -13mo not -12mo"], + ], + [ + common1Month4, common2Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -13, 0, 0, "M05-M05 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth5, common2Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -12, 0, 0, "M05-M05 leap-common backwards is -12mo"], + ], + [ + common1Month5, common2Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month4, leapMonth4L, + [-1, -1, 0, 0, "M04-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M04-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, -12, 0, 0, "M04L-M04 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M04 backwards is -12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, -12, 0, 0, "M05-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M05-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common2Month5, + [-1, -1, 0, 0, "M04L-M05 backwards is -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M05 backwards is -13mo"], + ], + [ + common1Month6, leapMonth5, + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 13, 0, 0, "M04-M04 common-leap is 13mo not 12mo"], + ], + [ + leapMonth4, common1Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 12, 0, 0, "M04-M04 leap-common is 12mo not 13mo"], + ], + [ + common2Month4, common1Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common2Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 12, 0, 0, "M05-M05 common-leap is 12mo not 13mo"], + ], + [ + leapMonth5, common1Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 13, 0, 0, "M05-M05 leap-common is 13mo not 12mo"], + ], + [ + common2Month5, common1Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, 12, 0, 0, "M04-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M04-M04L is 12mo"], + ], + [ + leapMonth4L, common1Month4, + [1, 0, 0, 0, "M04L-M04 is 1y not 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M04 is 13mo"], + ], + [ + common2Month5, leapMonth4L, + [1, 1, 0, 0, "M05-M04L is 1y 1mo"], + [0, 13, 0, 0, "M05-M04L is 13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, 12, 0, 0, "M04L-M05 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M05 is 12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-dangi.js b/test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-dangi.js new file mode 100644 index 0000000000..659c1a5cfe --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/since/leap-months-dangi.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in dangi calendar +esid: sec-temporal.zoneddatetime.prototype.since +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month5 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month6 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4L = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth5 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month4 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month5 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -12, 0, 0, "M04-M04 common-leap backwards is -12mo"], + ], + [ + leapMonth4, common2Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -13, 0, 0, "M04-M04 leap-common backwards is -13mo not -12mo"], + ], + [ + common1Month4, common2Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -13, 0, 0, "M05-M05 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth5, common2Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -12, 0, 0, "M05-M05 leap-common backwards is -12mo"], + ], + [ + common1Month5, common2Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common1Month4, leapMonth4L, + [-1, -1, 0, 0, "M04-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M04-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, -12, 0, 0, "M04L-M04 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M04 backwards is -12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, -12, 0, 0, "M05-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M05-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common2Month5, + [-1, -1, 0, 0, "M04L-M05 backwards is -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M05 backwards is -13mo"], + ], + [ + common1Month6, leapMonth5, + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + [0, -12, 0, 0, "M06-M05 common-leap backwards is -12mo not -11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 13, 0, 0, "M04-M04 common-leap is 13mo not 12mo"], + ], + [ + leapMonth4, common1Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 12, 0, 0, "M04-M04 leap-common is 12mo not 13mo"], + ], + [ + common2Month4, common1Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common2Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 12, 0, 0, "M05-M05 common-leap is 12mo not 13mo"], + ], + [ + leapMonth5, common1Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 13, 0, 0, "M05-M05 leap-common is 13mo not 12mo"], + ], + [ + common2Month5, common1Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, 12, 0, 0, "M04-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M04-M04L is 12mo"], + ], + [ + leapMonth4L, common1Month4, + [1, 0, 0, 0, "M04L-M04 is 1y not 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M04 is 13mo"], + ], + [ + common2Month5, leapMonth4L, + [1, 1, 0, 0, "M05-M04L is 1y 1mo"], + [0, 13, 0, 0, "M05-M04L is 13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, 12, 0, 0, "M04L-M05 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M05 is 12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-chinese.js b/test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-chinese.js new file mode 100644 index 0000000000..c29e5bfb18 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-chinese.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in chinese calendar +esid: sec-temporal.zoneddatetime.prototype.until +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month5 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month6 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4L = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth5 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month4 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month5 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 12, 0, 0, "M04-M04 common-leap is 12mo"], + ], + [ + leapMonth4, common2Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 13, 0, 0, "M04-M04 leap-common is 13mo not 12mo"], + ], + [ + common1Month4, common2Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common1Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 13, 0, 0, "M05-M05 common-leap is 13mo not 12mo"], + ], + [ + leapMonth5, common2Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 12, 0, 0, "M05-M05 leap-common is 12mo"], + ], + [ + common1Month5, common2Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common1Month4, leapMonth4L, + [1, 1, 0, 0, "M04-M04L is 1y 1mo"], + [0, 13, 0, 0, "M04-M04L is 13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, 12, 0, 0, "M04L-M04 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M04 is 12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, 12, 0, 0, "M05-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M05-M04L is 12mo"], + ], + [ + leapMonth4L, common2Month5, + [1, 1, 0, 0, "M04L-M05 is 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M05 is 13mo"], + ], + [ + common1Month6, leapMonth5, + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -13, 0, 0, "M04-M04 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth4, common1Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -12, 0, 0, "M04-M04 leap-common backwards is -12mo not -13mo"], + ], + [ + common2Month4, common1Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -12, 0, 0, "M05-M05 common-leap backwards is -12mo not -13mo"], + ], + [ + leapMonth5, common1Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -13, 0, 0, "M05-M05 leap-common backwards is -13mo not -12mo"], + ], + [ + common2Month5, common1Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, -12, 0, 0, "M04-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common1Month4, + [-1, 0, 0, 0, "M04L-M04 backwards is -1y not -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M04 backwards is -13mo"], + ], + [ + common2Month5, leapMonth4L, + [-1, -1, 0, 0, "M05-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M05-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, -12, 0, 0, "M04L-M05 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M05 backwards is -12mo"], + ], +]; + +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`); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-dangi.js b/test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-dangi.js new file mode 100644 index 0000000000..7a729b814b --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/until/leap-months-dangi.js @@ -0,0 +1,164 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Difference across leap months in dangi calendar +esid: sec-temporal.zoneddatetime.prototype.until +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +// 2001 is a leap year with a M04L leap month. + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const common1Month4 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month5 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common1Month6 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth4L = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M04L", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const leapMonth5 = Temporal.ZonedDateTime.from({ year: 2001, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month4 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M04", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const common2Month5 = Temporal.ZonedDateTime.from({ year: 2002, monthCode: "M05", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); + +// (receiver, argument, years test data, months test data) +// test data: expected years, months, weeks, days, description +// largestUnit years: make sure some cases where the answer is 12 months do not +// balance up to 1 year +// largestUnit months: similar to years, but make sure number of months in year +// is computed correctly +// For largestUnit of days and weeks, the results should be identical to what +// the ISO calendar gives for the corresponding ISO dates +const tests = [ + [ + common1Month4, leapMonth4, + [1, 0, 0, 0, "M04-M04 common-leap is 1y"], + [0, 12, 0, 0, "M04-M04 common-leap is 12mo"], + ], + [ + leapMonth4, common2Month4, + [1, 0, 0, 0, "M04-M04 leap-common is 1y"], + [0, 13, 0, 0, "M04-M04 leap-common is 13mo not 12mo"], + ], + [ + common1Month4, common2Month4, + [2, 0, 0, 0, "M04-M04 common-common is 2y"], + [0, 25, 0, 0, "M04-M04 common-common is 25mo not 24mo"], + ], + [ + common1Month5, leapMonth5, + [1, 0, 0, 0, "M05-M05 common-leap is 1y"], + [0, 13, 0, 0, "M05-M05 common-leap is 13mo not 12mo"], + ], + [ + leapMonth5, common2Month5, + [1, 0, 0, 0, "M05-M05 leap-common is 1y"], + [0, 12, 0, 0, "M05-M05 leap-common is 12mo"], + ], + [ + common1Month5, common2Month5, + [2, 0, 0, 0, "M05-M05 common-common is 2y"], + [0, 25, 0, 0, "M05-M05 common-common is 25mo not 24mo"], + ], + [ + common1Month4, leapMonth4L, + [1, 1, 0, 0, "M04-M04L is 1y 1mo"], + [0, 13, 0, 0, "M04-M04L is 13mo"], + ], + [ + leapMonth4L, common2Month4, + [0, 12, 0, 0, "M04L-M04 is 12mo not 1y"], + [0, 12, 0, 0, "M04L-M04 is 12mo"], + ], + [ + common1Month5, leapMonth4L, + [0, 12, 0, 0, "M05-M04L is 12mo not 1y"], + [0, 12, 0, 0, "M05-M04L is 12mo"], + ], + [ + leapMonth4L, common2Month5, + [1, 1, 0, 0, "M04L-M05 is 1y 1mo (exhibits calendar-specific constraining)"], + [0, 13, 0, 0, "M04L-M05 is 13mo"], + ], + [ + common1Month6, leapMonth5, + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + [0, 12, 0, 0, "M06-M05 common-leap is 12mo not 11mo"], + ], + + // Negative + [ + common2Month4, leapMonth4, + [-1, 0, 0, 0, "M04-M04 common-leap backwards is -1y"], + [0, -13, 0, 0, "M04-M04 common-leap backwards is -13mo not -12mo"], + ], + [ + leapMonth4, common1Month4, + [-1, 0, 0, 0, "M04-M04 leap-common backwards is -1y"], + [0, -12, 0, 0, "M04-M04 leap-common backwards is -12mo not -13mo"], + ], + [ + common2Month4, common1Month4, + [-2, 0, 0, 0, "M04-M04 common-common backwards is -2y"], + [0, -25, 0, 0, "M04-M04 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month5, leapMonth5, + [-1, 0, 0, 0, "M05-M05 common-leap backwards is -1y"], + [0, -12, 0, 0, "M05-M05 common-leap backwards is -12mo not -13mo"], + ], + [ + leapMonth5, common1Month5, + [-1, 0, 0, 0, "M05-M05 leap-common backwards is -1y"], + [0, -13, 0, 0, "M05-M05 leap-common backwards is -13mo not -12mo"], + ], + [ + common2Month5, common1Month5, + [-2, 0, 0, 0, "M05-M05 common-common backwards is -2y"], + [0, -25, 0, 0, "M05-M05 common-common backwards is -25mo not -24mo"], + ], + [ + common2Month4, leapMonth4L, + [0, -12, 0, 0, "M04-M04L backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04-M04L backwards is -12mo"], + ], + [ + leapMonth4L, common1Month4, + [-1, 0, 0, 0, "M04L-M04 backwards is -1y not -1y -1mo (exhibits calendar-specific constraining)"], + [0, -13, 0, 0, "M04L-M04 backwards is -13mo"], + ], + [ + common2Month5, leapMonth4L, + [-1, -1, 0, 0, "M05-M04L backwards is -1y -1mo"], + [0, -13, 0, 0, "M05-M04L backwards is -13mo"], + ], + [ + leapMonth4L, common1Month5, + [0, -12, 0, 0, "M04L-M05 backwards is -12mo not -1y"], + [0, -12, 0, 0, "M04L-M05 backwards is -12mo"], + ], +]; + +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`); +}