From 5ad17a206863c3163e8c13d972db488cfccba02a Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 19 Nov 2025 14:29:39 -0800 Subject: [PATCH] Temporal: Wrapping at end of month, Coptic, Ethioaa, and Ethiopic calendars Also correct some of the error message strings in the wrapping-at-end-of-month-gregory tests --- .../since/wrapping-at-end-of-month-coptic.js | 121 ++++++++++++++++++ .../since/wrapping-at-end-of-month-ethioaa.js | 121 ++++++++++++++++++ .../wrapping-at-end-of-month-ethiopic.js | 121 ++++++++++++++++++ .../since/wrapping-at-end-of-month-gregory.js | 4 +- .../until/wrapping-at-end-of-month-coptic.js | 121 ++++++++++++++++++ .../until/wrapping-at-end-of-month-ethioaa.js | 121 ++++++++++++++++++ .../wrapping-at-end-of-month-ethiopic.js | 121 ++++++++++++++++++ .../until/wrapping-at-end-of-month-gregory.js | 4 +- .../since/wrapping-at-end-of-month-coptic.js | 121 ++++++++++++++++++ .../since/wrapping-at-end-of-month-ethioaa.js | 121 ++++++++++++++++++ .../wrapping-at-end-of-month-ethiopic.js | 121 ++++++++++++++++++ .../since/wrapping-at-end-of-month-gregory.js | 4 +- .../until/wrapping-at-end-of-month-coptic.js | 121 ++++++++++++++++++ .../until/wrapping-at-end-of-month-ethioaa.js | 121 ++++++++++++++++++ .../wrapping-at-end-of-month-ethiopic.js | 121 ++++++++++++++++++ .../until/wrapping-at-end-of-month-gregory.js | 4 +- .../since/wrapping-at-end-of-month-coptic.js | 121 ++++++++++++++++++ .../since/wrapping-at-end-of-month-ethioaa.js | 121 ++++++++++++++++++ .../wrapping-at-end-of-month-ethiopic.js | 121 ++++++++++++++++++ .../since/wrapping-at-end-of-month-gregory.js | 4 +- .../until/wrapping-at-end-of-month-coptic.js | 121 ++++++++++++++++++ .../until/wrapping-at-end-of-month-ethioaa.js | 121 ++++++++++++++++++ .../wrapping-at-end-of-month-ethiopic.js | 121 ++++++++++++++++++ .../until/wrapping-at-end-of-month-gregory.js | 4 +- 24 files changed, 2190 insertions(+), 12 deletions(-) create mode 100644 test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-coptic.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethioaa.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethiopic.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-coptic.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethioaa.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethiopic.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-coptic.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-coptic.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-coptic.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-coptic.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js diff --git a/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-coptic.js b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-coptic.js new file mode 100644 index 0000000000..c82b434a71 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-coptic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (coptic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "coptic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pi Kogi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 28, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pi Kogi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 29, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pi Kogi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 30, calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pi Kogi Enavot (M13) +{ + const end = Temporal.PlainDate.from({ year: 1971, monthCode: "M13", day: 6, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 6, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pi Kogi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 29, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pi Kogi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 30, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 5, calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pi Kogi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 6, calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pi Kogi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDate.from({ year: 1973, monthCode: "M13", day: 5, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 6, calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pi Kogi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 7, calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 29, calendar }) + .since(Temporal.PlainDate.from({ year: 1970, monthCode: "M03", day: 28, calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 30, calendar }) + .since(Temporal.PlainDate.from({ year: 1971, monthCode: "M05", day: 29, calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethioaa.js b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethioaa.js new file mode 100644 index 0000000000..de6fcb17a6 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethioaa.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethioaa calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethioaa"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 28, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 29, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 30, calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDate.from({ year: 1971, monthCode: "M13", day: 6, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 6, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 29, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 30, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 5, calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 6, calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDate.from({ year: 1973, monthCode: "M13", day: 5, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 6, calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 7, calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 29, calendar }) + .since(Temporal.PlainDate.from({ year: 1970, monthCode: "M03", day: 28, calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 30, calendar }) + .since(Temporal.PlainDate.from({ year: 1971, monthCode: "M05", day: 29, calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethiopic.js b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethiopic.js new file mode 100644 index 0000000000..8079bcfcfe --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-ethiopic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethiopic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 28, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 29, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 30, calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDate.from({ year: 1971, monthCode: "M13", day: 6, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 6, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 29, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 30, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 5, calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 6, calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDate.from({ year: 1973, monthCode: "M13", day: 5, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 6, calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 7, calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 29, calendar }) + .since(Temporal.PlainDate.from({ year: 1970, monthCode: "M03", day: 28, calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 30, calendar }) + .since(Temporal.PlainDate.from({ year: 1971, monthCode: "M05", day: 29, calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-gregory.js b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-gregory.js index 6970189529..b2d6778bc7 100644 --- a/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-gregory.js +++ b/test/intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-gregory.js @@ -94,12 +94,12 @@ const calendar = "gregory"; TemporalHelpers.assertDuration( Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 31, calendar }).since(end, { largestUnit: "months" }), 0, -27, 0, -30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" + "Dec 31st 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" ); TemporalHelpers.assertDuration( Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 31, calendar }).since(end, { largestUnit: "years" }), -2, -3, 0, -30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" + "Dec 31st 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" ); } diff --git a/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-coptic.js b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-coptic.js new file mode 100644 index 0000000000..adef7cf46e --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-coptic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (coptic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "coptic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pi Kogi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 28, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pi Kogi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 29, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pi Kogi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 30, calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pi Kogi Enavot (M13) +{ + const end = Temporal.PlainDate.from({ year: 1971, monthCode: "M13", day: 6, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 6, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pi Kogi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 29, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pi Kogi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 30, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 5, calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pi Kogi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 6, calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pi Kogi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDate.from({ year: 1973, monthCode: "M13", day: 5, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 6, calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pi Kogi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 7, calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 29, calendar }) + .until(Temporal.PlainDate.from({ year: 1970, monthCode: "M03", day: 28, calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 30, calendar }) + .until(Temporal.PlainDate.from({ year: 1971, monthCode: "M05", day: 29, calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethioaa.js b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethioaa.js new file mode 100644 index 0000000000..c52da476b5 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethioaa.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethioaa calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethioaa"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 28, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 29, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 30, calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDate.from({ year: 1971, monthCode: "M13", day: 6, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 6, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 29, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 30, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 5, calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 6, calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDate.from({ year: 1973, monthCode: "M13", day: 5, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 6, calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 7, calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 29, calendar }) + .until(Temporal.PlainDate.from({ year: 1970, monthCode: "M03", day: 28, calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 30, calendar }) + .until(Temporal.PlainDate.from({ year: 1971, monthCode: "M05", day: 29, calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethiopic.js b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethiopic.js new file mode 100644 index 0000000000..bd89b5530b --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-ethiopic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethiopic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 28, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 29, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 30, calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDate.from({ year: 1971, monthCode: "M13", day: 6, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 6, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 29, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1971, monthCode: "M12", day: 30, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDate.from({ year: 1970, monthCode: "M13", day: 5, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 5, calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M10", day: 6, calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDate.from({ year: 1973, monthCode: "M13", day: 5, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 5, calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 6, calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 7, calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 29, calendar }) + .until(Temporal.PlainDate.from({ year: 1970, monthCode: "M03", day: 28, calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDate.from({ year: 1970, monthCode: "M01", day: 30, calendar }) + .until(Temporal.PlainDate.from({ year: 1971, monthCode: "M05", day: 29, calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-gregory.js b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-gregory.js index 68312867cd..8424c77831 100644 --- a/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-gregory.js +++ b/test/intl402/Temporal/PlainDate/prototype/until/wrapping-at-end-of-month-gregory.js @@ -94,12 +94,12 @@ const calendar = "gregory"; TemporalHelpers.assertDuration( Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 31, calendar }).until(end, { largestUnit: "months" }), 0, 27, 0, 30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" + "Dec 31st 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" ); TemporalHelpers.assertDuration( Temporal.PlainDate.from({ year: 1970, monthCode: "M12", day: 31, calendar }).until(end, { largestUnit: "years" }), 2, 3, 0, 30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" + "Dec 31st 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" ); } diff --git a/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-coptic.js b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-coptic.js new file mode 100644 index 0000000000..48c0b76148 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-coptic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (coptic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "coptic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pi Kogi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pi Kogi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pi Kogi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pi Kogi Enavot (M13) +{ + const end = Temporal.PlainDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pi Kogi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pi Kogi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pi Kogi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pi Kogi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pi Kogi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, calendar }) + .since(Temporal.PlainDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }) + .since(Temporal.PlainDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js new file mode 100644 index 0000000000..7283d1a7f1 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethioaa calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethioaa"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, calendar }) + .since(Temporal.PlainDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }) + .since(Temporal.PlainDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js new file mode 100644 index 0000000000..a40d304ffe --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethiopic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, calendar }) + .since(Temporal.PlainDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }) + .since(Temporal.PlainDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-gregory.js b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-gregory.js index 1fc33f081a..5163120933 100644 --- a/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-gregory.js +++ b/test/intl402/Temporal/PlainDateTime/prototype/since/wrapping-at-end-of-month-gregory.js @@ -94,12 +94,12 @@ const calendar = "gregory"; TemporalHelpers.assertDuration( Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "months" }), 0, -27, 0, -30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" + "Dec 31st 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" ); TemporalHelpers.assertDuration( Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, calendar }).since(end, { largestUnit: "years" }), -2, -3, 0, -30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" + "Dec 31st 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" ); } diff --git a/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-coptic.js b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-coptic.js new file mode 100644 index 0000000000..684a6a6e17 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-coptic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (coptic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "coptic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pi Kogi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pi Kogi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pi Kogi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pi Kogi Enavot (M13) +{ + const end = Temporal.PlainDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pi Kogi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pi Kogi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pi Kogi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pi Kogi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pi Kogi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, calendar }) + .until(Temporal.PlainDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }) + .until(Temporal.PlainDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js new file mode 100644 index 0000000000..919e6d3ab4 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethioaa calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethioaa"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, calendar }) + .until(Temporal.PlainDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }) + .until(Temporal.PlainDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js new file mode 100644 index 0000000000..69b18681ed --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethiopic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.PlainDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.PlainDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.PlainDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, calendar }); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, calendar }) + .until(Temporal.PlainDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.PlainDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }) + .until(Temporal.PlainDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-gregory.js b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-gregory.js index ce388f5c82..c06e1fc721 100644 --- a/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-gregory.js +++ b/test/intl402/Temporal/PlainDateTime/prototype/until/wrapping-at-end-of-month-gregory.js @@ -94,12 +94,12 @@ const calendar = "gregory"; TemporalHelpers.assertDuration( Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "months" }), 0, 27, 0, 30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" + "Dec 31st 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" ); TemporalHelpers.assertDuration( Temporal.PlainDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, calendar }).until(end, { largestUnit: "years" }), 2, 3, 0, 30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" + "Dec 31st 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" ); } diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-coptic.js b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-coptic.js new file mode 100644 index 0000000000..01c54a030f --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-coptic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (coptic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "coptic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pi Kogi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pi Kogi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pi Kogi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pi Kogi Enavot (M13) +{ + const end = Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pi Kogi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pi Kogi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pi Kogi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pi Kogi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.ZonedDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pi Kogi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .since(Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .since(Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js new file mode 100644 index 0000000000..4a19562180 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethioaa.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethioaa calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethioaa"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.ZonedDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .since(Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .since(Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js new file mode 100644 index 0000000000..e2bee04149 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-ethiopic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethiopic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit }), + 0, -2, 0, -29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.ZonedDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "months" }), + 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "years" }), + -3, -1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "months" }), + 0, -39, 0, -29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "years" }), + -3, 0, 0, -28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .since(Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "months" }), + 0, -1, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .since(Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "years" }), + -1, -3, 0, -29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-gregory.js b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-gregory.js index cacb3970e7..1c1e16db52 100644 --- a/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-gregory.js +++ b/test/intl402/Temporal/ZonedDateTime/prototype/since/wrapping-at-end-of-month-gregory.js @@ -94,12 +94,12 @@ const calendar = "gregory"; TemporalHelpers.assertDuration( Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "months" }), 0, -27, 0, -30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" + "Dec 31st 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" ); TemporalHelpers.assertDuration( Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, timeZone: "UTC", calendar }).since(end, { largestUnit: "years" }), -2, -3, 0, -30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" + "Dec 31st 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" ); } diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-coptic.js b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-coptic.js new file mode 100644 index 0000000000..3b076fe9b6 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-coptic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (coptic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "coptic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pi Kogi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pi Kogi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pi Kogi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pi Kogi Enavot (M13) +{ + const end = Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pi Kogi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pi Kogi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pi Kogi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pi Kogi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pi Kogi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.ZonedDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pi Kogi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pi Kogi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .until(Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .until(Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js new file mode 100644 index 0000000000..a2d87ddd00 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethioaa.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethioaa calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethioaa"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.ZonedDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .until(Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .until(Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js new file mode 100644 index 0000000000..6c7cab75b8 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-ethiopic.js @@ -0,0 +1,121 @@ +// 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: Tests balancing of days to months at end of month (ethiopic calendar) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; + +// Difference between end of longer month to end of following shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 5th to Pikougi Enavot 5th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 28th to Pikougi Enavot 5th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 29th to Pikougi Enavot 5th is 6 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 5th is 5 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of leap-year Mesori (M12) to end of leap-year Pikougi Enavot (M13) +{ + const end = Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M13", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + `Mesori 6th to Pikougi Enavot 6th is one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + `Mesori 31st to Pikougi Enavot 6th is 7 days, not one month (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + `Mesori 30th to Pikougi Enavot 6th is 6 days, not one month (${largestUnit})` + ); + } +} + +// Difference between end of longer month to end of not-immediately-following +// shorter month +{ + const end = Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + for (const largestUnit of ["years", "months"]) { + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + `Paoni 5th to Pikougi Enavot 5th is 3 months (${largestUnit})` + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M10", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit }), + 0, 2, 0, 29, 0, 0, 0, 0, 0, 0, + `Paoni 6th to Pikougi Enavot 5th is 2 months 29 days, not 3 months (${largestUnit})` + ); + } +} + +// Difference between end of longer month in one year to shorter month in +// later year +{ + const end = Temporal.ZonedDateTime.from({ year: 1973, monthCode: "M13", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "months" }), + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 5, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "years" }), + 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + "Mesori 5th 1970 to Pikougi Enavot 5th 1973 is 3 years, 1 month" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 6, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "months" }), + 0, 39, 0, 29, 0, 0, 0, 0, 0, 0, + "Mesori 6th 1970 to Pikougi Enavot 5th 1973 is 39 months, 29 days, not 40 months" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 7, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "years" }), + 3, 0, 0, 28, 0, 0, 0, 0, 0, 0, + "Mesori 7th 1970 to Pikougi Enavot 5th 1973 is 3 years, 28 days" + ); +} + +// Difference where months passes through a month that's the same length or +// shorter than either the start or end month +{ + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .until(Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M03", day: 28, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "months" }), + 0, 1, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 29th to Hathor 28th is 1 month 29 days, not 59 days" + ); + TemporalHelpers.assertDuration( + Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }) + .until(Temporal.ZonedDateTime.from({ year: 1971, monthCode: "M05", day: 29, hour: 12, minute: 34, timeZone: "UTC", calendar }), { largestUnit: "years" }), + 1, 3, 0, 29, 0, 0, 0, 0, 0, 0, + "Thout 30th 1970 to Tobi 29th 1971 is 1 year, 3 months, 29 days, not 1 year, 2 months, 59 days" + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-gregory.js b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-gregory.js index 20e9557ac4..0dd4a3371a 100644 --- a/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-gregory.js +++ b/test/intl402/Temporal/ZonedDateTime/prototype/until/wrapping-at-end-of-month-gregory.js @@ -94,12 +94,12 @@ const calendar = "gregory"; TemporalHelpers.assertDuration( Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "months" }), 0, 27, 0, 30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" + "Dec 31st 1970 to Apr 30th 1973 is 27 months, 30 days, not 28 months" ); TemporalHelpers.assertDuration( Temporal.ZonedDateTime.from({ year: 1970, monthCode: "M12", day: 31, hour: 12, minute: 34, timeZone: "UTC", calendar }).until(end, { largestUnit: "years" }), 2, 3, 0, 30, 0, 0, 0, 0, 0, 0, - "Dec 30th 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" + "Dec 31st 1970 to Apr 30th 1973 is 2 years, 3 months, 30 days, not 2 years 4 months" ); }