From 23d34b74d1ba069e808ceccbac23baa22d1b11a5 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 22 Jan 2026 12:53:34 -0800 Subject: [PATCH 1/2] Temporal: Adjust PlainYearMonth addition tests to disallow lower units Durations with units lower than months are no longer allowed. (The lower units may be present but 0.) Adjust the existing PlainYearMonth addition tests to test this behaviour and delete tests that are now irrelevant. Normative change: https://github.com/tc39/proposal-temporal/pull/3253 Approved in 2026-01 TC39 plenary. --- .../prototype/add/argument-duration-max.js | 38 ++++----------- .../add/argument-duration-out-of-range.js | 42 ----------------- .../prototype/add/argument-lower-units.js | 47 +++++++++---------- .../prototype/add/argument-mixed-sign.js | 2 +- ...rgument-propertybag-optional-properties.js | 12 ++--- ...gument-string-negative-fractional-units.js | 17 ------- .../prototype/add/month-length.js | 28 ----------- .../prototype/add/order-of-operations.js | 16 +++---- .../PlainYearMonth/prototype/add/overflow.js | 26 ++++++++++ .../subtract-from-last-representable-month.js | 14 ++---- .../subtract/argument-duration-max.js | 38 ++++----------- .../argument-duration-out-of-range.js | 42 ----------------- .../subtract/argument-lower-units.js | 45 +++++++++--------- .../prototype/subtract/argument-mixed-sign.js | 2 +- ...rgument-propertybag-optional-properties.js | 12 ++--- ...gument-string-negative-fractional-units.js | 17 ------- .../prototype/subtract/month-length.js | 28 ----------- .../prototype/subtract/order-of-operations.js | 16 +++---- .../prototype/subtract/overflow.js | 26 ++++++++++ .../subtract-from-last-representable-month.js | 14 ++---- 20 files changed, 153 insertions(+), 329 deletions(-) delete mode 100644 test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-string-negative-fractional-units.js delete mode 100644 test/built-ins/Temporal/PlainYearMonth/prototype/add/month-length.js create mode 100644 test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow.js delete mode 100644 test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-string-negative-fractional-units.js delete mode 100644 test/built-ins/Temporal/PlainYearMonth/prototype/subtract/month-length.js create mode 100644 test/built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow.js diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-max.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-max.js index 6777178079b..d96ff7ba51b 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-max.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-max.js @@ -11,20 +11,10 @@ features: [Temporal] const instance = new Temporal.PlainYearMonth(1970, 1); const maxCases = [ - ["P273790Y8M12DT23H59M59.999999999S", "string with max years"], - [{ years: 273790, months: 8, days: 12, nanoseconds: 86399999999999 }, "property bag with max years"], - ["P3285488M12DT23H59M59.999999999S", "string with max months"], - [{ months: 3285488, days: 12, nanoseconds: 86399999999999 }, "property bag with max months"], - ["P14285714W2DT23H59M59.999999999S", "string with max weeks"], - [{ weeks: 14285714, days: 2, nanoseconds: 86399999999999 }, "property bag with max weeks"], - ["P100000000DT23H59M59.999999999S", "string with max days"], - [{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"], - ["PT2400000023H59M59.999999999S", "string with max hours"], - [{ hours: 2400000023, nanoseconds: 3599999999999 }, "property bag with max hours"], - ["PT144000001439M59.999999999S", "string with max minutes"], - [{ minutes: 144000001439, nanoseconds: 59999999999 }, "property bag with max minutes"], - ["PT8640000086399.999999999S", "string with max seconds"], - [{ seconds: 8640000086399, nanoseconds: 999999999 }, "property bag with max seconds"], + ["P273790Y8M", "string with max years"], + [{ years: 273790, months: 8 }, "property bag with max years"], + ["P3285488M", "string with max months"], + [{ months: 3285488 }, "property bag with max months"], ]; for (const [arg, descr] of maxCases) { @@ -33,23 +23,13 @@ for (const [arg, descr] of maxCases) { } const minCases = [ - ["-P273790Y8M42DT23H59M59.999999999S", "string with min years"], - [{ years: -273790, months: -8, days: -42, nanoseconds: -86399999999999 }, "property bag with min years"], - ["-P3285488M42DT23H59M59.999999999S", "string with min months"], - [{ months: -3285488, days: -42, nanoseconds: -86399999999999 }, "property bag with min months"], - ["-P14285718W5DT23H59M59.999999999S", "string with min weeks"], - [{ weeks: -14285718, days: -5, nanoseconds: -86399999999999 }, "property bag with min weeks"], - ["-P100000031DT23H59M59.999999999S", "string with min days"], - [{ days: -100000031, nanoseconds: -86399999999999 }, "property bag with min days"], - ["-PT2400000767H59M59.999999999S", "string with min hours"], - [{ hours: -2400000767, nanoseconds: -3599999999999 }, "property bag with min hours"], - ["-PT144000046079M59.999999999S", "string with min minutes"], - [{ minutes: -144000046079, nanoseconds: -59999999999 }, "property bag with min minutes"], - ["-PT8640002764799.999999999S", "string with min seconds"], - [{ seconds: -8640002764799, nanoseconds: -999999999 }, "property bag with min seconds"], + ["-P273790Y8M", "string with min years"], + [{ years: -273790, months: -8 }, "property bag with min years"], + ["-P3285488M", "string with min months"], + [{ months: -3285488 }, "property bag with min months"], ]; for (const [arg, descr] of minCases) { const result = instance.add(arg); - TemporalHelpers.assertPlainYearMonth(result, -271821, 4, "M04", `operation succeeds with ${descr}`); + TemporalHelpers.assertPlainYearMonth(result, -271821, 5, "M05", `operation succeeds with ${descr}`); } diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-out-of-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-out-of-range.js index ed822732cb6..38fdc72e44b 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-out-of-range.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-out-of-range.js @@ -23,48 +23,6 @@ const cases = [ [{ weeks: 4294967296 }, "property bag with weeks > max"], ["-P4294967296W", "string with weeks < min"], [{ weeks: -4294967296 }, "property bag with weeks < min"], - - // ceil(max safe integer / 86400) = 104249991375 - ["P104249991375D", "string with days > max"], - [{ days: 104249991375 }, "property bag with days > max"], - ["P104249991374DT24H", "string where hours balance into days > max"], - [{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"], - ["-P104249991375D", "string with days < min"], - [{ days: -104249991375 }, "property bag with days < min"], - ["-P104249991374DT24H", "string where hours balance into days < min"], - [{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"], - - // ceil(max safe integer / 3600) = 2501999792984 - ["PT2501999792984H", "string with hours > max"], - [{ hours: 2501999792984 }, "property bag with hours > max"], - ["PT2501999792983H60M", "string where minutes balance into hours > max"], - [{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"], - ["-PT2501999792984H", "string with hours < min"], - [{ hours: -2501999792984 }, "property bag with hours < min"], - ["-PT2501999792983H60M", "string where minutes balance into hours < min"], - [{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"], - - // ceil(max safe integer / 60) = 150119987579017 - ["PT150119987579017M", "string with minutes > max"], - [{ minutes: 150119987579017 }, "property bag with minutes > max"], - ["PT150119987579016M60S", "string where seconds balance into minutes > max"], - [{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"], - ["-PT150119987579017M", "string with minutes < min"], - [{ minutes: -150119987579017 }, "property bag with minutes < min"], - ["-PT150119987579016M60S", "string where seconds balance into minutes < min"], - [{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"], - - // 2^53 = 9007199254740992 - ["PT9007199254740992S", "string with seconds > max"], - [{ seconds: 9007199254740992 }, "property bag with seconds > max"], - [{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"], - [{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"], - [{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"], - ["-PT9007199254740992S", "string with seconds < min"], - [{ seconds: -9007199254740992 }, "property bag with seconds < min"], - [{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"], - [{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"], - [{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"], ]; for (const [arg, descr] of cases) { diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-lower-units.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-lower-units.js index 0913de5ec1d..12726fa2d06 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-lower-units.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-lower-units.js @@ -3,36 +3,35 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.add -description: Using lower units in add() works -includes: [temporalHelpers.js] +description: Using lower units in add() throws features: [Temporal] ---*/ const ym = Temporal.PlainYearMonth.from("2019-11"); const tests = [ - [{ days: 1 }, 2019, 11, "M11"], - [{ days: 29 }, 2019, 11, "M11"], - [{ hours: 1 }, 2019, 11, "M11"], - [{ minutes: 1 }, 2019, 11, "M11"], - [{ seconds: 1 }, 2019, 11, "M11"], - [{ milliseconds: 1 }, 2019, 11, "M11"], - [{ microseconds: 1 }, 2019, 11, "M11"], - [{ nanoseconds: 1 }, 2019, 11, "M11"], - [{ days: 30 }, 2019, 12, "M12"], - [{ days: 31 }, 2019, 12, "M12"], - [{ days: 60 }, 2019, 12, "M12"], - [{ days: 61 }, 2020, 1, "M01"], - [{ hours: 720 }, 2019, 12, "M12"], - [{ minutes: 43200 }, 2019, 12, "M12"], - [{ seconds: 2592000 }, 2019, 12, "M12"], - [{ milliseconds: 2592000_000 }, 2019, 12, "M12"], - [{ microseconds: 2592000_000_000 }, 2019, 12, "M12"], - [{ nanoseconds: 2592000_000_000_000 }, 2019, 12, "M12"], + { days: 1 }, + { days: 29 }, + { hours: 1 }, + { minutes: 1 }, + { seconds: 1 }, + { milliseconds: 1 }, + { microseconds: 1 }, + { nanoseconds: 1 }, + { days: 30 }, + { days: 31 }, + { days: 60 }, + { days: 61 }, + { hours: 720 }, + { minutes: 43200 }, + { seconds: 2592000 }, + { milliseconds: 2592000_000 }, + { microseconds: 2592000_000_000 }, + { nanoseconds: 2592000_000_000_000 }, ]; -for (const [argument, ...expected] of tests) { - TemporalHelpers.assertPlainYearMonth(ym.add(argument), ...expected, "no options"); - TemporalHelpers.assertPlainYearMonth(ym.add(argument, { overflow: "constrain" }), ...expected, "constrain"); - TemporalHelpers.assertPlainYearMonth(ym.add(argument, { overflow: "reject" }), ...expected, "reject"); +for (const argument of tests) { + assert.throws(RangeError, function () { ym.add(argument); }, "adding a unit lower than months should throw, no options"); + assert.throws(RangeError, function () { ym.add(argument, { overflow: "constrain" }); }, "adding a unit lower than months should throw, constrain"); + assert.throws(RangeError, function () { ym.add(argument, { overflow: "reject" }); }, "adding a unit lower than months should throw, reject"); } diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-mixed-sign.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-mixed-sign.js index 0096756af51..49eba8ac88a 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-mixed-sign.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-mixed-sign.js @@ -12,7 +12,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5); ["constrain", "reject"].forEach((overflow) => { assert.throws( RangeError, - () => instance.add({ hours: 1, minutes: -30 }, { overflow }), + () => instance.add({ years: 1, months: -3 }, { overflow }), `mixed positive and negative values always throw (overflow = "${overflow}")` ); }); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js index 86febf630ed..176cb55f545 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js @@ -4,22 +4,22 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.add description: > - A property bag missing optional properties is equivalent to a property bag - with all the optional properties having their default values + A duration property bag with value 0 for disallowed properties is the same as + a property bag with no disallowed properties features: [Temporal] ---*/ const instance = new Temporal.PlainYearMonth(1970, 1); const oneProperty = { - hours: 1, + months: 1, }; const allProperties = { years: 0, - months: 0, + months: 1, weeks: 0, days: 0, - hours: 1, + hours: 0, minutes: 0, seconds: 0, milliseconds: 0, @@ -28,4 +28,4 @@ const allProperties = { }; const resultWithout = instance.add(oneProperty); const resultWith = instance.add(allProperties); -assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); +assert(resultWithout.equals(resultWith), "results should be the same with 0 for disallowed properties and without disallowed properties"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-string-negative-fractional-units.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-string-negative-fractional-units.js deleted file mode 100644 index 92231565481..00000000000 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-string-negative-fractional-units.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainyearmonth.prototype.add -description: Strings with fractional duration units are treated with the correct sign -includes: [temporalHelpers.js] -features: [Temporal] ----*/ - -const instance = new Temporal.PlainYearMonth(2000, 5); - -const resultHours = instance.add("-PT24.567890123H"); -TemporalHelpers.assertPlainYearMonth(resultHours, 2000, 5, "M05", "negative fractional hours"); - -const resultMinutes = instance.add("-PT1440.567890123M"); -TemporalHelpers.assertPlainYearMonth(resultMinutes, 2000, 5, "M05", "negative fractional minutes"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/month-length.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/month-length.js deleted file mode 100644 index 2ccf6fbf8b1..00000000000 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/month-length.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2022 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainyearmonth.prototype.add -description: add() takes month length into account -includes: [temporalHelpers.js] -features: [Temporal] ----*/ - -const ym = Temporal.PlainYearMonth.from("2019-11"); - -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-02").add({ days: 27 }), - 2019, 2, "M02"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-02").add({ days: 28 }), - 2019, 3, "M03"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-02").add({ days: 28 }), - 2020, 2, "M02"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-02").add({ days: 29 }), - 2020, 3, "M03"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-11").add({ days: 29 }), - 2019, 11, "M11"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-11").add({ days: 30 }), - 2019, 12, "M12"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-01").add({ days: 30 }), - 2020, 1, "M01"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-01").add({ days: 31 }), - 2020, 2, "M02"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js index 0045f2fb5c6..28c737f28a7 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js @@ -52,14 +52,14 @@ const instance = new Temporal.PlainYearMonth(2000, 5); const fields = TemporalHelpers.propertyBagObserver(actual, { years: 1, months: 1, - weeks: 1, - days: 1, - hours: 1, - minutes: 1, - seconds: 1, - milliseconds: 1, - microseconds: 1, - nanoseconds: 1, + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, }, "fields"); const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow.js new file mode 100644 index 00000000000..e8df1231c9a --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow.js @@ -0,0 +1,26 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Overflow option has no effect in ISO 8601 calendar +features: [Temporal] +---*/ + +const year1 = new Temporal.Duration(1); +const year1n = new Temporal.Duration(-1); +const month1 = new Temporal.Duration(0, 1); +const month1n = new Temporal.Duration(0, -1); + +for (const year of [2023, 2024]) { + for (const month of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) { + const yearmonth = new Temporal.PlainYearMonth(year, month); + for (const duration of [year1, year1n, month1, month1n]) { + const resultConstrain = yearmonth.add(duration, { overflow: "constrain" }); + const resultReject = yearmonth.add(duration, { overflow: "reject" }); + assert.sameValue(resultReject.year, resultConstrain.year, "year should be identical"); + assert.sameValue(resultReject.month, resultConstrain.month, "month should be identical"); + assert.sameValue(resultReject.toString(), resultConstrain.toString(), "toString should be identical"); + } + } +} diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/subtract-from-last-representable-month.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/subtract-from-last-representable-month.js index 3c03b1bbcad..ece10803fe6 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/add/subtract-from-last-representable-month.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/subtract-from-last-representable-month.js @@ -3,19 +3,13 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.add -description: RangeError thrown when adding negative duration to last representable month. +description: Adding negative duration to last representable month works features: [Temporal] +includes: [temporalHelpers.js] ---*/ const lastMonth = new Temporal.PlainYearMonth(275760, 9); -// See https://tc39.es/proposal-temporal/#sec-temporal-adddurationtoyearmonth -// (step 10d) -assert.throws(RangeError, () => lastMonth.add({seconds: -1})); -assert.throws(RangeError, () => lastMonth.add({minutes: -1})); -assert.throws(RangeError, () => lastMonth.add({hours: -1})); -assert.throws(RangeError, () => lastMonth.add({days: -1})); -assert.throws(RangeError, () => lastMonth.add({weeks: -1})); -assert.throws(RangeError, () => lastMonth.add({months: -1})); -assert.throws(RangeError, () => lastMonth.add({years: -1})); +TemporalHelpers.assertPlainYearMonth(lastMonth.add({ months: -1 }), 275760, 8, "M08", "-1 month"); +TemporalHelpers.assertPlainYearMonth(lastMonth.add({ years: -1 }), 275759, 9, "M09", "-1 year"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-max.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-max.js index 35a651fc12d..5814133ea0c 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-max.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-max.js @@ -11,42 +11,22 @@ features: [Temporal] const instance = new Temporal.PlainYearMonth(1970, 1); const maxCases = [ - ["P273790Y8M42DT23H59M59.999999999S", "string with max years"], - [{ years: 273790, months: 8, days: 42, nanoseconds: 86399999999999 }, "property bag with max years"], - ["P3285488M42DT23H59M59.999999999S", "string with max months"], - [{ months: 3285488, days: 42, nanoseconds: 86399999999999 }, "property bag with max months"], - ["P14285718W5DT23H59M59.999999999S", "string with max weeks"], - [{ weeks: 14285718, days: 5, nanoseconds: 86399999999999 }, "property bag with max weeks"], - ["P100000031DT23H59M59.999999999S", "string with max days"], - [{ days: 100000031, nanoseconds: 86399999999999 }, "property bag with max days"], - ["PT2400000767H59M59.999999999S", "string with max hours"], - [{ hours: 2400000767, nanoseconds: 3599999999999 }, "property bag with max hours"], - ["PT144000046079M59.999999999S", "string with max minutes"], - [{ minutes: 144000046079, nanoseconds: 59999999999 }, "property bag with max minutes"], - ["PT8640002764799.999999999S", "string with max seconds"], - [{ seconds: 8640002764799, nanoseconds: 999999999 }, "property bag with max seconds"], + ["P273790Y8M", "string with max years"], + [{ years: 273790, months: 8 }, "property bag with max years"], + ["P3285488M", "string with max months"], + [{ months: 3285488 }, "property bag with max months"], ]; for (const [arg, descr] of maxCases) { const result = instance.subtract(arg); - TemporalHelpers.assertPlainYearMonth(result, -271821, 4, "M04", `operation succeeds with ${descr}`); + TemporalHelpers.assertPlainYearMonth(result, -271821, 5, "M05", `operation succeeds with ${descr}`); } const minCases = [ - ["-P273790Y8M12DT23H59M59.999999999S", "string with min years"], - [{ years: -273790, months: -8, days: -12, nanoseconds: -86399999999999 }, "property bag with min years"], - ["-P3285488M12DT23H59M59.999999999S", "string with min months"], - [{ months: -3285488, days: -12, nanoseconds: -86399999999999 }, "property bag with min months"], - ["-P14285714W2DT23H59M59.999999999S", "string with min weeks"], - [{ weeks: -14285714, days: -2, nanoseconds: -86399999999999 }, "property bag with min weeks"], - ["-P100000000DT23H59M59.999999999S", "string with min days"], - [{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"], - ["-PT2400000023H59M59.999999999S", "string with min hours"], - [{ hours: -2400000023, nanoseconds: -3599999999999 }, "property bag with min hours"], - ["-PT144000001439M59.999999999S", "string with min minutes"], - [{ minutes: -144000001439, nanoseconds: -59999999999 }, "property bag with min minutes"], - ["-PT8640000086399.999999999S", "string with min seconds"], - [{ seconds: -8640000086399, nanoseconds: -999999999 }, "property bag with min seconds"], + ["-P273790Y8M", "string with min years"], + [{ years: -273790, months: -8 }, "property bag with min years"], + ["-P3285488M", "string with min months"], + [{ months: -3285488 }, "property bag with min months"], ]; for (const [arg, descr] of minCases) { diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-out-of-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-out-of-range.js index b98e48946a9..0c87072b94a 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-out-of-range.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-out-of-range.js @@ -23,48 +23,6 @@ const cases = [ [{ weeks: 4294967296 }, "property bag with weeks > max"], ["-P4294967296W", "string with weeks < min"], [{ weeks: -4294967296 }, "property bag with weeks < min"], - - // ceil(max safe integer / 86400) = 104249991375 - ["P104249991375D", "string with days > max"], - [{ days: 104249991375 }, "property bag with days > max"], - ["P104249991374DT24H", "string where hours balance into days > max"], - [{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"], - ["-P104249991375D", "string with days < min"], - [{ days: -104249991375 }, "property bag with days < min"], - ["-P104249991374DT24H", "string where hours balance into days < min"], - [{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"], - - // ceil(max safe integer / 3600) = 2501999792984 - ["PT2501999792984H", "string with hours > max"], - [{ hours: 2501999792984 }, "property bag with hours > max"], - ["PT2501999792983H60M", "string where minutes balance into hours > max"], - [{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"], - ["-PT2501999792984H", "string with hours < min"], - [{ hours: -2501999792984 }, "property bag with hours < min"], - ["-PT2501999792983H60M", "string where minutes balance into hours < min"], - [{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"], - - // ceil(max safe integer / 60) = 150119987579017 - ["PT150119987579017M", "string with minutes > max"], - [{ minutes: 150119987579017 }, "property bag with minutes > max"], - ["PT150119987579016M60S", "string where seconds balance into minutes > max"], - [{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"], - ["-PT150119987579017M", "string with minutes < min"], - [{ minutes: -150119987579017 }, "property bag with minutes < min"], - ["-PT150119987579016M60S", "string where seconds balance into minutes < min"], - [{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"], - - // 2^53 = 9007199254740992 - ["PT9007199254740992S", "string with seconds > max"], - [{ seconds: 9007199254740992 }, "property bag with seconds > max"], - [{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"], - [{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"], - [{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"], - ["-PT9007199254740992S", "string with seconds < min"], - [{ seconds: -9007199254740992 }, "property bag with seconds < min"], - [{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"], - [{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"], - [{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"], ]; for (const [arg, descr] of cases) { diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-lower-units.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-lower-units.js index cabf2e45fd8..2663bbb6196 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-lower-units.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-lower-units.js @@ -3,35 +3,34 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.subtract -description: Using lower units in subtract() works -includes: [temporalHelpers.js] +description: Using lower units in subtract() throws features: [Temporal] ---*/ const ym = Temporal.PlainYearMonth.from("2019-11"); const tests = [ - [{ days: 1 }, 2019, 11, "M11"], - [{ hours: 1 }, 2019, 11, "M11"], - [{ minutes: 1 }, 2019, 11, "M11"], - [{ seconds: 1 }, 2019, 11, "M11"], - [{ milliseconds: 1 }, 2019, 11, "M11"], - [{ microseconds: 1 }, 2019, 11, "M11"], - [{ nanoseconds: 1 }, 2019, 11, "M11"], - [{ days: 29 }, 2019, 11, "M11"], - [{ days: 30 }, 2019, 10, "M10"], - [{ days: 60 }, 2019, 10, "M10"], - [{ days: 61 }, 2019, 9, "M09"], - [{ hours: 720 }, 2019, 10, "M10"], - [{ minutes: 43200 }, 2019, 10, "M10"], - [{ seconds: 2592000 }, 2019, 10, "M10"], - [{ milliseconds: 2592000_000 }, 2019, 10, "M10"], - [{ microseconds: 2592000_000_000 }, 2019, 10, "M10"], - [{ nanoseconds: 2592000_000_000_000 }, 2019, 10, "M10"], + { days: 1 }, + { hours: 1 }, + { minutes: 1 }, + { seconds: 1 }, + { milliseconds: 1 }, + { microseconds: 1 }, + { nanoseconds: 1 }, + { days: 29 }, + { days: 30 }, + { days: 60 }, + { days: 61 }, + { hours: 720 }, + { minutes: 43200 }, + { seconds: 2592000 }, + { milliseconds: 2592000_000 }, + { microseconds: 2592000_000_000 }, + { nanoseconds: 2592000_000_000_000 }, ]; -for (const [argument, ...expected] of tests) { - TemporalHelpers.assertPlainYearMonth(ym.subtract(argument), ...expected, "no options"); - TemporalHelpers.assertPlainYearMonth(ym.subtract(argument, { overflow: "constrain" }), ...expected, "constrain"); - TemporalHelpers.assertPlainYearMonth(ym.subtract(argument, { overflow: "reject" }), ...expected, "reject"); +for (const argument of tests) { + assert.throws(RangeError, function () { ym.subtract(argument); }, "subtracting a unit lower than months should throw, no options"); + assert.throws(RangeError, function () { ym.subtract(argument, { overflow: "constrain" }); }, "subtracting a unit lower than months should throw, constrain"); + assert.throws(RangeError, function () { ym.subtract(argument, { overflow: "reject" }); }, "subtracting a unit lower than months should throw, reject"); } diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-mixed-sign.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-mixed-sign.js index 955eb892624..6d6f0944f7e 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-mixed-sign.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-mixed-sign.js @@ -12,7 +12,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5); ["constrain", "reject"].forEach((overflow) => { assert.throws( RangeError, - () => instance.subtract({ hours: 1, minutes: -30 }, { overflow }), + () => instance.subtract({ years: 1, months: -3 }, { overflow }), `mixed positive and negative values always throw (overflow = "${overflow}")` ); }); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-propertybag-optional-properties.js index eeb79db6327..8afcd986326 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-propertybag-optional-properties.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-propertybag-optional-properties.js @@ -4,22 +4,22 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.subtract description: > - A property bag missing optional properties is equivalent to a property bag - with all the optional properties having their default values + A duration property bag with value 0 for disallowed properties is the same as + a property bag with no disallowed properties features: [Temporal] ---*/ const instance = new Temporal.PlainYearMonth(1970, 1); const oneProperty = { - hours: 1, + months: 1, }; const allProperties = { years: 0, - months: 0, + months: 1, weeks: 0, days: 0, - hours: 1, + hours: 0, minutes: 0, seconds: 0, milliseconds: 0, @@ -28,4 +28,4 @@ const allProperties = { }; const resultWithout = instance.subtract(oneProperty); const resultWith = instance.subtract(allProperties); -assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); +assert(resultWithout.equals(resultWith), "results should be the same with 0 for disallowed properties and without disallowed properties"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-string-negative-fractional-units.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-string-negative-fractional-units.js deleted file mode 100644 index 061060e979a..00000000000 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-string-negative-fractional-units.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainyearmonth.prototype.subtract -description: Strings with fractional duration units are treated with the correct sign -includes: [temporalHelpers.js] -features: [Temporal] ----*/ - -const instance = new Temporal.PlainYearMonth(2000, 5); - -const resultHours = instance.subtract("-PT24.567890123H"); -TemporalHelpers.assertPlainYearMonth(resultHours, 2000, 5, "M05", "negative fractional hours"); - -const resultMinutes = instance.subtract("-PT1440.567890123M"); -TemporalHelpers.assertPlainYearMonth(resultMinutes, 2000, 5, "M05", "negative fractional minutes"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/month-length.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/month-length.js deleted file mode 100644 index 39c71717edf..00000000000 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/month-length.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2022 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainyearmonth.prototype.subtract -description: subtract() takes month length into account -includes: [temporalHelpers.js] -features: [Temporal] ----*/ - -const ym = Temporal.PlainYearMonth.from("2019-11"); - -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-02").subtract({ days: 27 }), - 2019, 2, "M02"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-02").subtract({ days: 28 }), - 2019, 1, "M01"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-02").subtract({ days: 28 }), - 2020, 2, "M02"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-02").subtract({ days: 29 }), - 2020, 1, "M01"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-11").subtract({ days: 29 }), - 2019, 11, "M11"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2019-11").subtract({ days: 30 }), - 2019, 10, "M10"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-01").subtract({ days: 30 }), - 2020, 1, "M01"); -TemporalHelpers.assertPlainYearMonth(Temporal.PlainYearMonth.from("2020-01").subtract({ days: 31 }), - 2019, 12, "M12"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js index b376925ae6c..1dd450cb803 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js @@ -51,14 +51,14 @@ const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601"); const fields = TemporalHelpers.propertyBagObserver(actual, { years: 1, months: 1, - weeks: 1, - days: 1, - hours: 1, - minutes: 1, - seconds: 1, - milliseconds: 1, - microseconds: 1, - nanoseconds: 1, + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, }, "fields"); const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow.js new file mode 100644 index 00000000000..9c10a443847 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow.js @@ -0,0 +1,26 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Overflow option has no effect in ISO 8601 calendar +features: [Temporal] +---*/ + +const year1 = new Temporal.Duration(1); +const year1n = new Temporal.Duration(-1); +const month1 = new Temporal.Duration(0, 1); +const month1n = new Temporal.Duration(0, -1); + +for (const year of [2023, 2024]) { + for (const month of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) { + const yearmonth = new Temporal.PlainYearMonth(year, month); + for (const duration of [year1, year1n, month1, month1n]) { + const resultConstrain = yearmonth.subtract(duration, { overflow: "constrain" }); + const resultReject = yearmonth.subtract(duration, { overflow: "reject" }); + assert.sameValue(resultReject.year, resultConstrain.year, "year should be identical"); + assert.sameValue(resultReject.month, resultConstrain.month, "month should be identical"); + assert.sameValue(resultReject.toString(), resultConstrain.toString(), "toString should be identical"); + } + } +} diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/subtract-from-last-representable-month.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/subtract-from-last-representable-month.js index 841d95f122a..a0531a7b163 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/subtract-from-last-representable-month.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/subtract-from-last-representable-month.js @@ -3,19 +3,13 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.subtract -description: RangeError thrown when subtracting duration from last representable month. +description: Subtracting duration from last representable month works features: [Temporal] +includes: [temporalHelpers.js] ---*/ const lastMonth = new Temporal.PlainYearMonth(275760, 9); -// See https://tc39.es/proposal-temporal/#sec-temporal-adddurationtoyearmonth -// (step 10d) -assert.throws(RangeError, () => lastMonth.subtract({seconds: 1})); -assert.throws(RangeError, () => lastMonth.subtract({minutes: 1})); -assert.throws(RangeError, () => lastMonth.subtract({hours: 1})); -assert.throws(RangeError, () => lastMonth.subtract({days: 1})); -assert.throws(RangeError, () => lastMonth.subtract({weeks: 1})); -assert.throws(RangeError, () => lastMonth.subtract({months: 1})); -assert.throws(RangeError, () => lastMonth.subtract({years: 1})); +TemporalHelpers.assertPlainYearMonth(lastMonth.subtract({ months: 1 }), 275760, 8, "M08", "1 month"); +TemporalHelpers.assertPlainYearMonth(lastMonth.subtract({ years: 1 }), 275759, 9, "M09", "1 year"); From aff08c5ccce17a8b21d9748c5b9b149cb369c320 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 5 Dec 2025 15:45:25 -0800 Subject: [PATCH 2/2] Intl Era Monthcode: Add tests for PlainYearMonth addition in leap years I had previously postponed adding these tests because they were affected by https://github.com/tc39/proposal-temporal/issues/3197. Now that TC39 has adopted a solution to that bug, we can add these and increase test coverage for non-ISO8601 calendar addition in PlainYearMonth. --- .../prototype/add/leap-months-chinese.js | 320 +++++++++++++++++ .../prototype/add/leap-months-dangi.js | 320 +++++++++++++++++ .../prototype/add/leap-months-hebrew.js | 339 ++++++++++++++++++ .../prototype/add/leap-year-buddhist.js | 99 +++++ .../prototype/add/leap-year-coptic.js | 39 ++ .../prototype/add/leap-year-ethioaa.js | 39 ++ .../prototype/add/leap-year-ethiopic.js | 39 ++ .../prototype/add/leap-year-gregory.js | 99 +++++ .../prototype/add/leap-year-indian.js | 39 ++ .../prototype/add/leap-year-islamic-civil.js | 42 +++ .../prototype/add/leap-year-islamic-tbla.js | 42 +++ .../prototype/add/leap-year-japanese.js | 99 +++++ .../prototype/add/leap-year-persian.js | 90 +++++ .../prototype/add/leap-year-roc.js | 99 +++++ .../prototype/subtract/leap-months-chinese.js | 320 +++++++++++++++++ .../prototype/subtract/leap-months-dangi.js | 320 +++++++++++++++++ .../prototype/subtract/leap-months-hebrew.js | 339 ++++++++++++++++++ .../prototype/subtract/leap-year-buddhist.js | 97 +++++ .../prototype/subtract/leap-year-coptic.js | 39 ++ .../prototype/subtract/leap-year-ethioaa.js | 39 ++ .../prototype/subtract/leap-year-ethiopic.js | 39 ++ .../prototype/subtract/leap-year-gregory.js | 99 +++++ .../prototype/subtract/leap-year-indian.js | 39 ++ .../subtract/leap-year-islamic-civil.js | 42 +++ .../subtract/leap-year-islamic-tbla.js | 42 +++ .../prototype/subtract/leap-year-japanese.js | 99 +++++ .../prototype/subtract/leap-year-persian.js | 90 +++++ .../prototype/subtract/leap-year-roc.js | 99 +++++ 28 files changed, 3408 insertions(+) create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-chinese.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-dangi.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-hebrew.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-buddhist.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-coptic.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethioaa.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethiopic.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-gregory.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-indian.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-civil.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-tbla.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-japanese.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-persian.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-roc.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-chinese.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-dangi.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-hebrew.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-buddhist.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-coptic.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethioaa.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethiopic.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-gregory.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-indian.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-civil.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-tbla.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-japanese.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-persian.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-roc.js diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-chinese.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-chinese.js new file mode 100644 index 00000000000..b930ce8bc71 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-chinese.js @@ -0,0 +1,320 @@ +// 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.plainyearmonth.prototype.add +description: Arithmetic around leap months in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); + +const leap193807L = Temporal.PlainYearMonth.from({ year: 1938, monthCode: "M07L", calendar }, options); +const leap195205L = Temporal.PlainYearMonth.from({ year: 1952, monthCode: "M05L", calendar }, options); +const leap196603L = Temporal.PlainYearMonth.from({ year: 1966, monthCode: "M03L", calendar }, options); +const common200008 = Temporal.PlainYearMonth.from({ year: 2000, monthCode: "M08", calendar }, options); +const common200108 = Temporal.PlainYearMonth.from({ year: 2001, monthCode: "M08", calendar }, options); +const common201901 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M01", calendar }, options); +const common201904 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M04", calendar }, options); +const leap202004 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04", calendar }, options); +const leap202004L = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04L", calendar }, options); +const common202104 = Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + common201901.add(years1), + 2020, 1, "M01", "add 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.add(years1), + 1967, 3, "M03", "Adding 1 year to leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.add(years1, options); +}, "Adding 1 year to leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap193807L.add(years1), + 1939, 7, "M07", "Adding 1 year to leap month M07L on day 30 constrains to M07 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap193807L.add(years1, options); +}, "Adding 1 year to leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(years1, options), + 2020, 4, "M04", "Adding 1 year to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(years1, options), + 2021, 4, "M04", "Adding 1 year to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2012, monthCode: "M04L", calendar }, options).add(new Temporal.Duration(8), options), + 2020, 5, "M04L", "Adding years to go from one M04L to the next M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.add(years1, options), + 2001, 9, "M08", "Adding 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(new Temporal.Duration(2), options), + 2021, 4, "M04", "Adding 2 years to common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201901.add(years1n), + 2018, 1, "M01", "Subtracting 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.add(years1n), + 1965, 3, "M03", "Subtracting 1 year from leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.add(years1n, options); +}, "Subtracting 1 year from leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap195205L.add(years1n), + 1951, 5, "M05", "Subtracting 1 year from leap month M05L on day 30 constrains to M05 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap195205L.add(years1n, options); +}, "Subtracting 1 year from leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(years1n, options), + 2020, 4, "M04", "Subtracting 1 year from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(years1n, options), + 2019, 4, "M04", "Subtracting 1 year from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(new Temporal.Duration(-8), options), + 2012, 5, "M04L", "Subtracting years to go from one M04L to the previous M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.add(years1n, options), + 2000, 8, "M08", "Subtracting 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(new Temporal.Duration(-2), options), + 2019, 4, "M04", "Subtracting 2 years from common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +// Months + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months12 = new Temporal.Duration(0, 12); +const months12n = new Temporal.Duration(0, -12); +const months13 = new Temporal.Duration(0, 13); +const months13n = new Temporal.Duration(0, -13); + +const leap202003 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); +const leap202006 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M06", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1947, monthCode: "M02L", calendar }, options).add(months1), + 1947, 4, "M03", "add 1 month, starting at start of leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1955, monthCode: "M03L", calendar }, options).add(months1), + 1955, 5, "M04", "add 1 month, starting at start of leap month with 30 days", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.add(months1), + 2020, 4, "M04", "adding 1 month to M03 in leap year lands in M04 (not M04L)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.add(new Temporal.Duration(0, 2)), + 2020, 5, "M04L", "adding 2 months to M03 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.add(new Temporal.Duration(0, 3)), + 2020, 6, "M05", "adding 3 months to M03 in leap year lands in M05 (not M06)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(months12), + 2020, 4, "M04", "Adding 12 months to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(months13), + 2020, 5, "M04L", "Adding 13 months to common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(months12), + 2021, 3, "M03", "Adding 12 months to leap-year M04 lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(months13), + 2021, 4, "M04", "Adding 13 months to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months12), + 2021, 4, "M04", "Adding 12 months to M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.add(new Temporal.Duration(1, 12), options), + 2002, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.add(new Temporal.Duration(2, 13), options), + 2004, 9, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(new Temporal.Duration(0, 24)), + 2021, 3, "M03", "Adding 24 months to common-year M04 crossing leap year with M04L, lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(new Temporal.Duration(0, 25)), + 2021, 4, "M04", "Adding 25 months to common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.add(months1n), + 2020, 6, "M05", "Subtracting 1 month from M06 in leap year lands in M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.add(new Temporal.Duration(0, -2)), + 2020, 5, "M04L", "Subtracting 2 months from M06 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.add(new Temporal.Duration(0, -3)), + 2020, 4, "M04", "Subtracting 3 months from M06 in leap year lands in M04 (not M03)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M05", calendar }, options).add(months1n), + 2020, 5, "M04L", "Subtracting 1 month from M05 in leap year lands in M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months1n), + 2020, 4, "M04", "Subtracting 1 month from M04L in calendar lands in M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(months12n), + 2020, 5, "M04L", "Subtracting 12 months from common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(months13n), + 2020, 4, "M04", "Subtracting 13 months from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(months12n), + 2019, 4, "M04", "Subtracting 12 months from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months12n), + 2019, 5, "M05", "Subtracting 12 months from M04L lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months13n), + 2019, 4, "M04", "Subtracting 13 months from M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.add(new Temporal.Duration(-1, -12), options), + 1999, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.add(new Temporal.Duration(-2, -13), options), + 1997, 8, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(new Temporal.Duration(0, -24)), + 2019, 5, "M05", "Subtracting 24 months from common-year M04 crossing leap year with M04L, lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(new Temporal.Duration(0, -25)), + 2019, 4, "M04", "Subtracting 25 months from common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-dangi.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-dangi.js new file mode 100644 index 00000000000..8f71f0b4a6b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-dangi.js @@ -0,0 +1,320 @@ +// 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.plainyearmonth.prototype.add +description: Arithmetic around leap months in the dangi calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); + +const leap193807L = Temporal.PlainYearMonth.from({ year: 1938, monthCode: "M07L", calendar }, options); +const leap195205L = Temporal.PlainYearMonth.from({ year: 1952, monthCode: "M05L", calendar }, options); +const leap196603L = Temporal.PlainYearMonth.from({ year: 1966, monthCode: "M03L", calendar }, options); +const common200008 = Temporal.PlainYearMonth.from({ year: 2000, monthCode: "M08", calendar }, options); +const common200108 = Temporal.PlainYearMonth.from({ year: 2001, monthCode: "M08", calendar }, options); +const common201901 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M01", calendar }, options); +const common201904 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M04", calendar }, options); +const leap202004 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04", calendar }, options); +const leap202004L = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04L", calendar }, options); +const common202104 = Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + common201901.add(years1), + 2020, 1, "M01", "add 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.add(years1), + 1967, 3, "M03", "Adding 1 year to leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.add(years1, options); +}, "Adding 1 year to leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap193807L.add(years1), + 1939, 7, "M07", "Adding 1 year to leap month M07L on day 30 constrains to M07 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap193807L.add(years1, options); +}, "Adding 1 year to leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(years1, options), + 2020, 4, "M04", "Adding 1 year to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(years1, options), + 2021, 4, "M04", "Adding 1 year to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2012, monthCode: "M03L", calendar }, options).add(new Temporal.Duration(-19), options), + 1993, 4, "M03L", "Subtracting years to go from one M03L to the previous M03L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.add(years1, options), + 2001, 9, "M08", "Adding 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(new Temporal.Duration(2), options), + 2021, 4, "M04", "Adding 2 years to common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201901.add(years1n), + 2018, 1, "M01", "Subtracting 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.add(years1n), + 1965, 3, "M03", "Subtracting 1 year from leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.add(years1n, options); +}, "Subtracting 1 year from leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap195205L.add(years1n), + 1951, 5, "M05", "Subtracting 1 year from leap month M05L on day 30 constrains to M05 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap195205L.add(years1n, options); +}, "Subtracting 1 year from leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(years1n, options), + 2020, 4, "M04", "Subtracting 1 year from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(years1n, options), + 2019, 4, "M04", "Subtracting 1 year from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2012, monthCode: "M03L", calendar }, options).add(new Temporal.Duration(-19), options), + 1993, 4, "M03L", "Subtracting years to go from one M03L to the previous M03L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.add(years1n, options), + 2000, 8, "M08", "Subtracting 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(new Temporal.Duration(-2), options), + 2019, 4, "M04", "Subtracting 2 years from common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +// Months + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months12 = new Temporal.Duration(0, 12); +const months12n = new Temporal.Duration(0, -12); +const months13 = new Temporal.Duration(0, 13); +const months13n = new Temporal.Duration(0, -13); + +const leap202003 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); +const leap202006 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M06", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1947, monthCode: "M02L", calendar }, options).add(months1), + 1947, 4, "M03", "add 1 month, starting at start of leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1955, monthCode: "M03L", calendar }, options).add(months1), + 1955, 5, "M04", "add 1 month, starting at start of leap month with 30 days", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.add(months1), + 2020, 4, "M04", "adding 1 month to M03 in leap year lands in M04 (not M04L)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.add(new Temporal.Duration(0, 2)), + 2020, 5, "M04L", "adding 2 months to M03 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.add(new Temporal.Duration(0, 3)), + 2020, 6, "M05", "adding 3 months to M03 in leap year lands in M05 (not M06)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(months12), + 2020, 4, "M04", "Adding 12 months to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(months13), + 2020, 5, "M04L", "Adding 13 months to common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(months12), + 2021, 3, "M03", "Adding 12 months to leap-year M04 lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(months13), + 2021, 4, "M04", "Adding 13 months to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months12), + 2021, 4, "M04", "Adding 12 months to M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.add(new Temporal.Duration(1, 12), options), + 2002, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.add(new Temporal.Duration(2, 13), options), + 2004, 9, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(new Temporal.Duration(0, 24)), + 2021, 3, "M03", "Adding 24 months to common-year M04 crossing leap year with M04L, lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.add(new Temporal.Duration(0, 25)), + 2021, 4, "M04", "Adding 25 months to common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.add(months1n), + 2020, 6, "M05", "Subtracting 1 month from M06 in leap year lands in M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.add(new Temporal.Duration(0, -2)), + 2020, 5, "M04L", "Subtracting 2 months from M06 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.add(new Temporal.Duration(0, -3)), + 2020, 4, "M04", "Subtracting 3 months from M06 in leap year lands in M04 (not M03)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M05", calendar }, options).add(months1n), + 2020, 5, "M04L", "Subtracting 1 month from M05 in leap year lands in M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months1n), + 2020, 4, "M04", "Subtracting 1 month from M04L in calendar lands in M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(months12n), + 2020, 5, "M04L", "Subtracting 12 months from common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(months13n), + 2020, 4, "M04", "Subtracting 13 months from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.add(months12n), + 2019, 4, "M04", "Subtracting 12 months from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months12n), + 2019, 5, "M05", "Subtracting 12 months from M04L lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.add(months13n), + 2019, 4, "M04", "Subtracting 13 months from M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.add(new Temporal.Duration(-1, -12), options), + 1999, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.add(new Temporal.Duration(-2, -13), options), + 1997, 8, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(new Temporal.Duration(0, -24)), + 2019, 5, "M05", "Subtracting 24 months from common-year M04 crossing leap year with M04L, lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.add(new Temporal.Duration(0, -25)), + 2019, 4, "M04", "Subtracting 25 months from common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-hebrew.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-hebrew.js new file mode 100644 index 00000000000..19657f9ea71 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-months-hebrew.js @@ -0,0 +1,339 @@ +// 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.plainyearmonth.prototype.add +description: Arithmetic around leap months in the hebrew calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "hebrew"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years2 = new Temporal.Duration(2); +const years2n = new Temporal.Duration(-2); + +const leap1AdarI = Temporal.PlainYearMonth.from({ year: 5782, monthCode: "M05L", calendar }, options); +const leap1AdarII = Temporal.PlainYearMonth.from({ year: 5782, monthCode: "M06", calendar }, options); +const common1Adar = Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M06", calendar }, options); +const common = Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M08", calendar }, options); +const leap2AdarI = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M05L", calendar }, options); +const leap2AdarII = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M06", calendar }, options); +const common2Adar = Temporal.PlainYearMonth.from({ year: 5785, monthCode: "M06", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.add(years1, options), + 5784, 7, "M06", "Adding 1 year to common-year Adar (M06) lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.add(years2, options), + 5785, 6, "M06", "Adding 2 years to common-year Adar (M06) crossing leap year lands in common-year Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(years1), + 5785, 6, "M06", "Adding 1 year to Adar I (M05L) lands in common-year Adar (M06) with constrain", + "am", 5785, null +); + +assert.throws(RangeError, function () { + leap2AdarI.add(years1, options); +}, "Adding 1 year to Adar I (M05L) rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.add(years1, options), + 5785, 6, "M06", "Adding 1 year to Adar II (M06) lands in common-year Adar (M06) even with reject", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + common.add(years1, options), + 5784, 9, "M08", "Adding 1 year across Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarI.add(years2, options), + 5784, 6, "M05L", "Adding 2 years to leap-year Adar I (M05L) lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarII.add(years2, options), + 5784, 7, "M06", "Adding 2 years to leap-year Adar II (M06) lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.add(years1n, options), + 5784, 7, "M06", "Subtracting 1 year from common-year Adar (M06) lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.add(years2n, options), + 5783, 6, "M06", "Subtracting 2 years from common-year Adar (M06) crossing leap year lands in common-year Adar (M06)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(years1n), + 5783, 6, "M06", "Subtracting 1 year from Adar I (M05L) lands in common-year Adar (M06) with constrain", + "am", 5783, null +); + +assert.throws(RangeError, function () { + leap2AdarI.add(years1n, options); +}, "Subtracting 1 year from Adar I (M05L) rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.add(years1n, options), + 5783, 6, "M06", "Subtracting 1 year from Adar II (M06) lands in common-year Adar (M06) even with reject", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common.add(years2n, options), + 5781, 8, "M08", "Subtracting 2 years across Adar I (M05L)", + "am", 5781, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(years2n, options), + 5782, 6, "M05L", "Subtracting 2 years from leap-year Adar I (M05L) lands in leap-year Adar I (M05L)", + "am", 5782, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.add(years2n, options), + 5782, 7, "M06", "Subtracting 2 years from leap-year Adar II (M06) lands in leap-year Adar II (M06)", + "am", 5782, null +); + +// Months + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months2 = new Temporal.Duration(0, 2); +const months2n = new Temporal.Duration(0, -2); +const months12 = new Temporal.Duration(0, 12); +const months12n = new Temporal.Duration(0, -12); +const months13 = new Temporal.Duration(0, 13); +const months13n = new Temporal.Duration(0, -13); +const months24 = new Temporal.Duration(0, 24); +const months24n = new Temporal.Duration(0, -24); + +const date1 = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M04", calendar }, options); +const date3 = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M07", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date1.add(months1, options), + 5784, 5, "M05", "Adding 1 month to M04 in leap year lands in M05 (Shevat)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.add(months2, options), + 5784, 6, "M05L", "Adding 2 months to M04 in leap year lands in M05L (Adar I)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.add(new Temporal.Duration(0, 3), options), + 5784, 7, "M06", "Adding 3 months to M04 in leap year lands in M06 (Adar II)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(months1, options), + 5784, 7, "M06", "Adding 1 month to M05L (Adar I) lands in M06 (Adar II)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M04", calendar }, options).add(months2, options), + 5783, 6, "M06", "Adding 2 months to M04 in non-leap year lands in M06 (no M05L)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.add(months12, options), + 5784, 6, "M05L", "Adding 12 months to common-year Adar lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.add(months13, options), + 5784, 7, "M06", "Adding 13 months to common-year Adar lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(months12, options), + 5785, 5, "M05", "Adding 12 months to leap-year Adar I lands in Shevat (M05)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(months13, options), + 5785, 6, "M06", "Adding 13 months to leap-year Adar I lands in Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.add(months12, options), + 5785, 6, "M06", "Adding 12 months to leap-year Adar II lands in Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + common.add(months13, options), + 5784, 9, "M08", "Adding 13 months across Adar I (M05L) lands in same month code", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common.add(new Temporal.Duration(1, 12), options), + 5785, 8, "M08", "Adding 1y 12mo across Adar I (M05L) in the years part lands in same month code", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.add(new Temporal.Duration(2, 13), options), + 5787, 8, "M07", "Adding 2y 13mo across Adar I (M05L) in the months part lands in same month code", + "am", 5787, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.add(months24, options), + 5785, 5, "M05", "Adding 24 months to common-year Adar crossing a leap year lands in common-year Shevat (M05)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.add(new Temporal.Duration(0, 25), options), + 5785, 6, "M06", "Adding 25 months to common-year Adar crossing a leap year lands in common-year Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarI.add(months24, options), + 5784, 5, "M05", "Adding 24 months to leap-year Adar I lands in leap-year Shevat (M05)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarII.add(months24, options), + 5784, 6, "M05L", "Adding 24 months to leap-year Adar II lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.add(months1n, options), + 5784, 7, "M06", "Subtracting 1 month from M07 in leap year lands in M06 (Adar II)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.add(months2n, options), + 5784, 6, "M05L", "Subtracting 2 months from M07 in leap year lands in M05L (Adar I)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.add(new Temporal.Duration(0, -3), options), + 5784, 5, "M05", "Subtracting 3 months from M07 in leap year lands in M05 (Shevat)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.add(months1n, options), + 5784, 6, "M05L", "Subtracting 1 month from M06 (Adar II) in leap year lands in M05L (Adar I)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(months1n, options), + 5784, 5, "M05", "Subtracting 1 month from M05L (Adar I) lands in M05 (Shevat)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M07", calendar }).add(months2n, options), + 5783, 5, "M05", "Subtracting 2 months from M07 in non-leap year lands in M05 (no M05L)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.add(months12n, options), + 5784, 7, "M06", "Subtracting 12 months from common-year Adar lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.add(months13n, options), + 5784, 6, "M05L", "Subtracting 13 months from common-year Adar lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(months12n, options), + 5783, 6, "M06", "Subtracting 12 months from leap-year Adar I lands in Adar (M06)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(months13n, options), + 5783, 5, "M05", "Subtracting 13 months from leap-year Adar I lands in Shevat (M05)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.add(months12n, options), + 5783, 7, "M07", "Subtracting 12 months from leap-year Adar II lands in Nisan (M07)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.add(months24n, options), + 5783, 7, "M07", "Subtracting 24 months from common-year Adar crossing a leap year lands in common-year Nisan (M07)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.add(new Temporal.Duration(-2, -12), options), + 5781, 4, "M04", "Subtracting 2y 12mo across Adar I (M05L) in the years part lands in same month code", + "am", 5781, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.add(new Temporal.Duration(-1, -13), options), + 5782, 4, "M04", "Subtracting 1y 13mo across Adar I (M05L) in the months part lands in same month code", + "am", 5782, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.add(new Temporal.Duration(0, -25), options), + 5783, 6, "M06", "Subtracting 25 months from common-year Adar crossing a leap year lands in common-year Adar (M06)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.add(months24n, options), + 5782, 7, "M06", "Subtracting 24 months from leap-year Adar I lands in leap-year Adar (M06)", + "am", 5782, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.add(months24n, options), + 5782, 8, "M07", "Subtracting 24 months from leap-year Adar II lands in leap-year Nisan (M07)", + "am", 5782, null +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-buddhist.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-buddhist.js new file mode 100644 index 00000000000..09acab8da61 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-buddhist.js @@ -0,0 +1,99 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (buddhist calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "buddhist"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +const date256302 = Temporal.PlainYearMonth.from({ year: 2563, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date256302.add(years1, options), + 2564, 2, "M02", "add 1y to Feb", + "be", 2564); + +TemporalHelpers.assertPlainYearMonth( + date256302.add(years4, options), + 2567, 2, "M02", "add 4y to Feb", + "be", 2567); + +TemporalHelpers.assertPlainYearMonth( + date256302.add(years1n, options), + 2562, 2, "M02", "subtract 1y from Feb", + "be", 2562); + +TemporalHelpers.assertPlainYearMonth( + date256302.add(years4n, options), + 2559, 2, "M02", "subtract 4y from Feb", + "be", 2559); + +// Months + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months5 = new Temporal.Duration(0, 5); +const months11n = new Temporal.Duration(0, -11); +const years1months2 = new Temporal.Duration(1, 2); +const years1months2n = new Temporal.Duration(-1, -2); + +const date256301 = Temporal.PlainYearMonth.from({ year: 2563, monthCode: "M01", calendar }, options); +const date256303 = Temporal.PlainYearMonth.from({ year: 2563, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date256301.add(months1, options), + 2563, 2, "M02", "add 1mo to Jan in leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M09", calendar }, options).add(months5), + 2565, 2, "M02", "add 5mo with result in the next year", + "be", 2565); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2562, monthCode: "M09", calendar }, options).add(months5), + 2563, 2, "M02", "add 5mo with result in the next leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M12", calendar }, options).add(years1months2), + 2566, 2, "M02", "add 1y 2mo with result in the next year", + "be", 2566); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2565, monthCode: "M12", calendar }, options).add(years1months2), + 2567, 2, "M02", "add 1y 2mo with result in the next leap year", + "be", 2567); + +TemporalHelpers.assertPlainYearMonth( + date256303.add(months1n, options), + 2563, 2, "M02", "subtract 1mo from Mar in leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + date256301.add(months11n), + 2562, 2, "M02", "subtract 11mo with result in the previous year", + "be", 2562); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M01", calendar }, options).add(months11n), + 2563, 2, "M02", "add 11mo with result in the previous leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2565, monthCode: "M04", calendar }, options).add(years1months2n), + 2564, 2, "M02", "add 1y 2mo with result in the previous year", + "be", 2564); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M04", calendar }, options).add(years1months2n), + 2563, 2, "M02", "add 1y 2mo with result in the previous leap year", + "be", 2563); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-coptic.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-coptic.js new file mode 100644 index 00000000000..6855921f23b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-coptic.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (coptic calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "coptic"; +const options = { overflow: "reject" }; + +const epagomenalMonth = Temporal.PlainYearMonth.from({ year: 1739, monthCode: "M13", calendar }, options); + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years1, options), + 1740, 13, "M13", "Adding 1 year to epagomenal month", + "am", 1740, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years1n, options), + 1738, 13, "M13", "Subtracting 1 year from epagomenal month", + "am", 1738, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years4, options), + 1743, 13, "M13", "Adding 4 years to epagomenal month", + "am", 1743, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years4n, options), + 1735, 13, "M13", "Subtracting 4 years from epagomenal month", + "am", 1735, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethioaa.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethioaa.js new file mode 100644 index 00000000000..dcb0c69ab90 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethioaa.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (ethioaa calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "ethioaa"; +const options = { overflow: "reject" }; + +const epagomenalMonth = Temporal.PlainYearMonth.from({ year: 7515, monthCode: "M13", calendar }, options); + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years1, options), + 7516, 13, "M13", "Adding 1 year to epagomenal month", + "aa", 7516, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years1n, options), + 7514, 13, "M13", "Subtracting 1 year from epagomenal month", + "aa", 7514, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years4, options), + 7519, 13, "M13", "Adding 4 years to epagomenal month", + "aa", 7519, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years4n, options), + 7511, 13, "M13", "Subtracting 4 years from epagomenal month", + "aa", 7511, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethiopic.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethiopic.js new file mode 100644 index 00000000000..6e90bd0c508 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-ethiopic.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (ethiopic calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "ethiopic"; +const options = { overflow: "reject" }; + +const epagomenalMonth = Temporal.PlainYearMonth.from({ year: 2015, monthCode: "M13", calendar }, options); + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years1, options), + 2016, 13, "M13", "Adding 1 year to epagomenal month", + "am", 2016, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years1n, options), + 2014, 13, "M13", "Subtracting 1 year from epagomenal month", + "am", 2014, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years4, options), + 2019, 13, "M13", "Adding 4 years to epagomenal month", + "am", 2019, null); + +TemporalHelpers.assertPlainYearMonth( + epagomenalMonth.add(years4n, options), + 2011, 13, "M13", "Subtracting 4 years from epagomenal month", + "am", 2011, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-gregory.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-gregory.js new file mode 100644 index 00000000000..e450d899a0c --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-gregory.js @@ -0,0 +1,99 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (gregory calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "gregory"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +const date202002 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years1, options), + 2021, 2, "M02", "add 1y to Feb", + "ce", 2021); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years4, options), + 2024, 2, "M02", "add 4y to Feb", + "ce", 2024); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years1n, options), + 2019, 2, "M02", "subtract 1y from Feb", + "ce", 2019); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years4n, options), + 2016, 2, "M02", "subtract 4y from Feb", + "ce", 2016); + +// Months + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months5 = new Temporal.Duration(0, 5); +const months11n = new Temporal.Duration(0, -11); +const years1months2 = new Temporal.Duration(1, 2); +const years1months2n = new Temporal.Duration(-1, -2); + +const date202001 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M01", calendar }, options); +const date202003 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date202001.add(months1, options), + 2020, 2, "M02", "add 1mo to Jan in leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M09", calendar }, options).add(months5), + 2022, 2, "M02", "add 5mo with result in the next year", + "ce", 2022); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M09", calendar }, options).add(months5), + 2020, 2, "M02", "add 5mo with result in the next leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M12", calendar }, options).add(years1months2), + 2023, 2, "M02", "add 1y 2mo with result in the next year", + "ce", 2023); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M12", calendar }, options).add(years1months2), + 2024, 2, "M02", "add 1y 2mo with result in the next leap year", + "ce", 2024); + +TemporalHelpers.assertPlainYearMonth( + date202003.add(months1n, options), + 2020, 2, "M02", "subtract 1mo from Mar in leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + date202001.add(months11n), + 2019, 2, "M02", "subtract 11mo with result in the previous year", + "ce", 2019); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M01", calendar }, options).add(months11n), + 2020, 2, "M02", "add 11mo with result in the previous leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M04", calendar }, options).add(years1months2n), + 2021, 2, "M02", "add 1y 2mo with result in the previous year", + "ce", 2021); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options).add(years1months2n), + 2020, 2, "M02", "add 1y 2mo with result in the previous leap year", + "ce", 2020); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-indian.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-indian.js new file mode 100644 index 00000000000..aa48f902407 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-indian.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (indian calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "indian"; +const options = { overflow: "reject" }; + +const leap = Temporal.PlainYearMonth.from({ year: 1946, monthCode: "M01", calendar }, options); + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +TemporalHelpers.assertPlainYearMonth( + leap.add(years1, options), + 1947, 1, "M01", "Adding 1 year to Chaitra", + "shaka", 1947, null); + +TemporalHelpers.assertPlainYearMonth( + leap.add(years1n, options), + 1945, 1, "M01", "Subtracting 1 year from Chaitra", + "shaka", 1945, null); + +TemporalHelpers.assertPlainYearMonth( + leap.add(years4, options), + 1950, 1, "M01", "Adding 4 years to Chaitra", + "shaka", 1950, null); + +TemporalHelpers.assertPlainYearMonth( + leap.add(years4n, options), + 1942, 1, "M01", "Subtracting 4 years from Chaitra", + "shaka", 1942, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-civil.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-civil.js new file mode 100644 index 00000000000..41130482a53 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-civil.js @@ -0,0 +1,42 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (islamic-civil calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "islamic-civil"; +const options = { overflow: "reject" }; + +// Month 12 (Dhu al-Hijjah) has 29 days in common years and 30 in leap years. +// AH 1442, 1445, and 1447 are leap years. + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years2 = new Temporal.Duration(2); +const years3n = new Temporal.Duration(-3); + +const date144512 = Temporal.PlainYearMonth.from({ year: 1445, monthCode: "M12", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years1, options), + 1446, 12, "M12", "add 1y to leap", + "ah", 1446, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years2, options), + 1447, 12, "M12", "add 2y to leap landing in next leap year", + "ah", 1447, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years1n, options), + 1444, 12, "M12", "subtract 1y from leap", + "ah", 1444, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years3n, options), + 1442, 12, "M12", "subtract 3y from leap landing in previous leap year", + "ah", 1442, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-tbla.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-tbla.js new file mode 100644 index 00000000000..7beb849612d --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-islamic-tbla.js @@ -0,0 +1,42 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (islamic-tbla calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "islamic-tbla"; +const options = { overflow: "reject" }; + +// Month 12 (Dhu al-Hijjah) has 29 days in common years and 30 in leap years. +// AH 1442, 1445, and 1447 are leap years. + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years2 = new Temporal.Duration(2); +const years3n = new Temporal.Duration(-3); + +const date144512 = Temporal.PlainYearMonth.from({ year: 1445, monthCode: "M12", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years1, options), + 1446, 12, "M12", "add 1y to leap", + "ah", 1446, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years2, options), + 1447, 12, "M12", "add 2y to leap landing in next leap year", + "ah", 1447, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years1n, options), + 1444, 12, "M12", "subtract 1y from leap", + "ah", 1444, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.add(years3n, options), + 1442, 12, "M12", "subtract 3y from leap landing in previous leap year", + "ah", 1442, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-japanese.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-japanese.js new file mode 100644 index 00000000000..82d4de97a52 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-japanese.js @@ -0,0 +1,99 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (japanese calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "japanese"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +const date202002 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years1, options), + 2021, 2, "M02", "add 1y to Feb", + "reiwa", 3); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years4, options), + 2024, 2, "M02", "add 4y to Feb", + "reiwa", 6); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years1n, options), + 2019, 2, "M02", "subtract 1y from Feb", + "heisei", 31); + +TemporalHelpers.assertPlainYearMonth( + date202002.add(years4n, options), + 2016, 2, "M02", "subtract 4y from Feb", + "heisei", 28); + +// Months + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months5 = new Temporal.Duration(0, 5); +const months11n = new Temporal.Duration(0, -11); +const years1months2 = new Temporal.Duration(1, 2); +const years1months2n = new Temporal.Duration(-1, -2); + +const date20200131 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M01", calendar }, options); +const date20200331 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date20200131.add(months1, options), + 2020, 2, "M02", "add 1mo to Jan in leap year", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M09", calendar }, options).add(months5), + 2022, 2, "M02", "add 5mo with result in the next year", + "reiwa", 4); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M09", calendar }, options).add(months5), + 2020, 2, "M02", "add 5mo with result in the next leap year", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M12", calendar }, options).add(years1months2), + 2023, 2, "M02", "add 1y 2mo with result in the next year", + "reiwa", 5); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M12", calendar }, options).add(years1months2), + 2024, 2, "M02", "add 1y 2mo with result in the next leap year", + "reiwa", 6); + +TemporalHelpers.assertPlainYearMonth( + date20200331.add(months1n, options), + 2020, 2, "M02", "subtract 1mo from Mar in leap year", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + date20200131.add(months11n), + 2019, 2, "M02", "subtract 11mo with result in the previous year", + "heisei", 31); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M01", calendar }, options).add(months11n), + 2020, 2, "M02", "add 11mo with result in the previous leap year", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M04", calendar }, options).add(years1months2n), + 2021, 2, "M02", "add 1y 2mo with result in the previous year", + "reiwa", 3); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options).add(years1months2n), + 2020, 2, "M02", "add 1y 2mo with result in the previous leap year", + "reiwa", 2); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-persian.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-persian.js new file mode 100644 index 00000000000..0a32c26f400 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-persian.js @@ -0,0 +1,90 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (Persian calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "persian"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +const date136212 = Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M12", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date136212.add(years1, options), + 1363, 12, "M12", "add 1y to leap", + "ap", 1363, null); + +TemporalHelpers.assertPlainYearMonth( + date136212.add(years4, options), + 1366, 12, "M12", "add 4y to leap", + "ap", 1366, null); + +TemporalHelpers.assertPlainYearMonth( + date136212.add(years1n, options), + 1361, 12, "M12", "subtract 1y from leap", + "ap", 1361, null); + +TemporalHelpers.assertPlainYearMonth( + date136212.add(years4n, options), + 1358, 12, "M12", "subtract 4y from leap", + "ap", 1358, null); + +// Months + +const months1n = new Temporal.Duration(0, -1); +const months6 = new Temporal.Duration(0, 6); +const months11n = new Temporal.Duration(0, -11); +const years1months2 = new Temporal.Duration(1, 2); +const years1months2n = new Temporal.Duration(-1, -2); + +const date136206 = Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M06", calendar }, options); +const date136211 = Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M11", calendar }, options); +const date136301 = Temporal.PlainYearMonth.from({ year: 1363, monthCode: "M01", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date136206.add(months6, options), + 1362, 12, "M12", "add 6mo to Shahrivar in leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M10", calendar }, options).add(years1months2), + 1363, 12, "M12", "add 1y 2mo with result in the next year", + "ap", 1363, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1361, monthCode: "M10", calendar }, options).add(years1months2), + 1362, 12, "M12", "add 1y 2mo with result in the next leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + date136301.add(months1n, options), + 1362, 12, "M12", "subtract 1mo from Farvardin in leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + date136211.add(months11n), + 1361, 12, "M12", "subtract 11mo with result in the previous year", + "ap", 1361, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1363, monthCode: "M11", calendar }, options).add(months11n), + 1362, 12, "M12", "subtract 11mo with result in the previous leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1364, monthCode: "M02", calendar }, options).add(years1months2n), + 1362, 12, "M12", "add 1y 2mo with result in the previous year", + "ap", 1362, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1365, monthCode: "M02", calendar }, options).add(years1months2n), + 1363, 12, "M12", "add 1y 2mo with result in the previous leap year", + "ap", 1363, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-roc.js b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-roc.js new file mode 100644 index 00000000000..2ea854afccf --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/add/leap-year-roc.js @@ -0,0 +1,99 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Check various basic calculations involving leap years (roc calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "roc"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(1); +const years1n = new Temporal.Duration(-1); +const years4 = new Temporal.Duration(4); +const years4n = new Temporal.Duration(-4); + +const date10902 = Temporal.PlainYearMonth.from({ year: 109, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date10902.add(years1, options), + 110, 2, "M02", "add 1y to Feb", + "roc", 110); + +TemporalHelpers.assertPlainYearMonth( + date10902.add(years4, options), + 113, 2, "M02", "add 4y to Feb", + "roc", 113); + +TemporalHelpers.assertPlainYearMonth( + date10902.add(years1n, options), + 108, 2, "M02", "subtract 1y from Feb", + "roc", 108); + +TemporalHelpers.assertPlainYearMonth( + date10902.add(years4n, options), + 105, 2, "M02", "subtract 4y from Feb", + "roc", 105); + +// Months + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months5 = new Temporal.Duration(0, 5); +const months11n = new Temporal.Duration(0, -11); +const years1months2 = new Temporal.Duration(1, 2); +const years1months2n = new Temporal.Duration(-1, -2); + +const date1090131 = Temporal.PlainYearMonth.from({ year: 109, monthCode: "M01", calendar }, options); +const date1090331 = Temporal.PlainYearMonth.from({ year: 109, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date1090131.add(months1, options), + 109, 2, "M02", "add 1mo to Jan in leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M09", calendar }, options).add(months5), + 111, 2, "M02", "add 5mo with result in the next year", + "roc", 111); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 108, monthCode: "M09", calendar }, options).add(months5), + 109, 2, "M02", "add 5mo with result in the next leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M12", calendar }, options).add(years1months2), + 112, 2, "M02", "add 1y 2mo with result in the next year", + "roc", 112); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 111, monthCode: "M12", calendar }, options).add(years1months2), + 113, 2, "M02", "add 1y 2mo with result in the next leap year", + "roc", 113); + +TemporalHelpers.assertPlainYearMonth( + date1090331.add(months1n, options), + 109, 2, "M02", "subtract 1mo from Mar in leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + date1090131.add(months11n), + 108, 2, "M02", "subtract 11mo with result in the previous year", + "roc", 108); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M01", calendar }, options).add(months11n), + 109, 2, "M02", "add 11mo with result in the previous leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 111, monthCode: "M04", calendar }, options).add(years1months2n), + 110, 2, "M02", "add 1y 2mo with result in the previous year", + "roc", 110); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M04", calendar }, options).add(years1months2n), + 109, 2, "M02", "add 1y 2mo with result in the previous leap year", + "roc", 109); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-chinese.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-chinese.js new file mode 100644 index 00000000000..795ac5be310 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-chinese.js @@ -0,0 +1,320 @@ +// 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.plainyearmonth.prototype.subtract +description: Arithmetic around leap months in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); + +const leap193807L = Temporal.PlainYearMonth.from({ year: 1938, monthCode: "M07L", calendar }, options); +const leap195205L = Temporal.PlainYearMonth.from({ year: 1952, monthCode: "M05L", calendar }, options); +const leap196603L = Temporal.PlainYearMonth.from({ year: 1966, monthCode: "M03L", calendar }, options); +const common200008 = Temporal.PlainYearMonth.from({ year: 2000, monthCode: "M08", calendar }, options); +const common200108 = Temporal.PlainYearMonth.from({ year: 2001, monthCode: "M08", calendar }, options); +const common201901 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M01", calendar }, options); +const common201904 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M04", calendar }, options); +const leap202004 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04", calendar }, options); +const leap202004L = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04L", calendar }, options); +const common202104 = Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + common201901.subtract(years1), + 2020, 1, "M01", "add 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.subtract(years1), + 1967, 3, "M03", "Adding 1 year to leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.subtract(years1, options); +}, "Adding 1 year to leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap193807L.subtract(years1), + 1939, 7, "M07", "Adding 1 year to leap month M07L on day 30 constrains to M07 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap193807L.subtract(years1, options); +}, "Adding 1 year to leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(years1, options), + 2020, 4, "M04", "Adding 1 year to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(years1, options), + 2021, 4, "M04", "Adding 1 year to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2012, monthCode: "M04L", calendar }, options).subtract(new Temporal.Duration(-8), options), + 2020, 5, "M04L", "Adding years to go from one M04L to the next M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.subtract(years1, options), + 2001, 9, "M08", "Adding 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(new Temporal.Duration(-2), options), + 2021, 4, "M04", "Adding 2 years to common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201901.subtract(years1n), + 2018, 1, "M01", "Subtracting 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.subtract(years1n), + 1965, 3, "M03", "Subtracting 1 year from leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.subtract(years1n, options); +}, "Subtracting 1 year from leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap195205L.subtract(years1n), + 1951, 5, "M05", "Subtracting 1 year from leap month M05L on day 30 constrains to M05 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap195205L.subtract(years1n, options); +}, "Subtracting 1 year from leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(years1n, options), + 2020, 4, "M04", "Subtracting 1 year from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(years1n, options), + 2019, 4, "M04", "Subtracting 1 year from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(new Temporal.Duration(8), options), + 2012, 5, "M04L", "Subtracting years to go from one M04L to the previous M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.subtract(years1n, options), + 2000, 8, "M08", "Subtracting 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(new Temporal.Duration(2), options), + 2019, 4, "M04", "Subtracting 2 years from common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +// Months + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months12 = new Temporal.Duration(0, -12); +const months12n = new Temporal.Duration(0, 12); +const months13 = new Temporal.Duration(0, -13); +const months13n = new Temporal.Duration(0, 13); + +const leap202003 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); +const leap202006 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M06", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1947, monthCode: "M02L", calendar }, options).subtract(months1), + 1947, 4, "M03", "add 1 month, starting at start of leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1955, monthCode: "M03L", calendar }, options).subtract(months1), + 1955, 5, "M04", "add 1 month, starting at start of leap month with 30 days", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.subtract(months1), + 2020, 4, "M04", "adding 1 month to M03 in leap year lands in M04 (not M04L)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.subtract(new Temporal.Duration(0, -2)), + 2020, 5, "M04L", "adding 2 months to M03 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.subtract(new Temporal.Duration(0, -3)), + 2020, 6, "M05", "adding 3 months to M03 in leap year lands in M05 (not M06)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(months12), + 2020, 4, "M04", "Adding 12 months to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(months13), + 2020, 5, "M04L", "Adding 13 months to common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(months12), + 2021, 3, "M03", "Adding 12 months to leap-year M04 lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(months13), + 2021, 4, "M04", "Adding 13 months to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months12), + 2021, 4, "M04", "Adding 12 months to M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.subtract(new Temporal.Duration(-1, -12), options), + 2002, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.subtract(new Temporal.Duration(-2, -13), options), + 2004, 9, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(new Temporal.Duration(0, -24)), + 2021, 3, "M03", "Adding 24 months to common-year M04 crossing leap year with M04L, lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(new Temporal.Duration(0, -25)), + 2021, 4, "M04", "Adding 25 months to common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.subtract(months1n), + 2020, 6, "M05", "Subtracting 1 month from M06 in leap year lands in M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.subtract(new Temporal.Duration(0, 2)), + 2020, 5, "M04L", "Subtracting 2 months from M06 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.subtract(new Temporal.Duration(0, 3)), + 2020, 4, "M04", "Subtracting 3 months from M06 in leap year lands in M04 (not M03)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M05", calendar }, options).subtract(months1n), + 2020, 5, "M04L", "Subtracting 1 month from M05 in leap year lands in M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months1n), + 2020, 4, "M04", "Subtracting 1 month from M04L in calendar lands in M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(months12n), + 2020, 5, "M04L", "Subtracting 12 months from common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(months13n), + 2020, 4, "M04", "Subtracting 13 months from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(months12n), + 2019, 4, "M04", "Subtracting 12 months from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months12n), + 2019, 5, "M05", "Subtracting 12 months from M04L lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months13n), + 2019, 4, "M04", "Subtracting 13 months from M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.subtract(new Temporal.Duration(1, 12), options), + 1999, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.subtract(new Temporal.Duration(2, 13), options), + 1997, 8, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(new Temporal.Duration(0, 24)), + 2019, 5, "M05", "Subtracting 24 months from common-year M04 crossing leap year with M04L, lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(new Temporal.Duration(0, 25)), + 2019, 4, "M04", "Subtracting 25 months from common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-dangi.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-dangi.js new file mode 100644 index 00000000000..e2390a1a434 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-dangi.js @@ -0,0 +1,320 @@ +// 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.plainyearmonth.prototype.subtract +description: Arithmetic around leap months in the dangi calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); + +const leap193807L = Temporal.PlainYearMonth.from({ year: 1938, monthCode: "M07L", calendar }, options); +const leap195205L = Temporal.PlainYearMonth.from({ year: 1952, monthCode: "M05L", calendar }, options); +const leap196603L = Temporal.PlainYearMonth.from({ year: 1966, monthCode: "M03L", calendar }, options); +const common200008 = Temporal.PlainYearMonth.from({ year: 2000, monthCode: "M08", calendar }, options); +const common200108 = Temporal.PlainYearMonth.from({ year: 2001, monthCode: "M08", calendar }, options); +const common201901 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M01", calendar }, options); +const common201904 = Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M04", calendar }, options); +const leap202004 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04", calendar }, options); +const leap202004L = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M04L", calendar }, options); +const common202104 = Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + common201901.subtract(years1), + 2020, 1, "M01", "add 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.subtract(years1), + 1967, 3, "M03", "Adding 1 year to leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.subtract(years1, options); +}, "Adding 1 year to leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap193807L.subtract(years1), + 1939, 7, "M07", "Adding 1 year to leap month M07L on day 30 constrains to M07 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap193807L.subtract(years1, options); +}, "Adding 1 year to leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(years1, options), + 2020, 4, "M04", "Adding 1 year to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(years1, options), + 2021, 4, "M04", "Adding 1 year to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2012, monthCode: "M03L", calendar }, options).subtract(new Temporal.Duration(19), options), + 1993, 4, "M03L", "Subtracting years to go from one M03L to the previous M03L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.subtract(years1, options), + 2001, 9, "M08", "Adding 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(new Temporal.Duration(-2), options), + 2021, 4, "M04", "Adding 2 years to common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201901.subtract(years1n), + 2018, 1, "M01", "Subtracting 1 year from non-leap day", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap196603L.subtract(years1n), + 1965, 3, "M03", "Subtracting 1 year from leap month M03L lands in common-year M03 with overflow constrain", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap196603L.subtract(years1n, options); +}, "Subtracting 1 year from leap month rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap195205L.subtract(years1n), + 1951, 5, "M05", "Subtracting 1 year from leap month M05L on day 30 constrains to M05 day 29", + undefined, undefined, null +); + +assert.throws(RangeError, function () { + leap195205L.subtract(years1n, options); +}, "Subtracting 1 year from leap month day 30 rejects"); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(years1n, options), + 2020, 4, "M04", "Subtracting 1 year from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(years1n, options), + 2019, 4, "M04", "Subtracting 1 year from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2012, monthCode: "M03L", calendar }, options).subtract(new Temporal.Duration(19), options), + 1993, 4, "M03L", "Subtracting years to go from one M03L to the previous M03L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.subtract(years1n, options), + 2000, 8, "M08", "Subtracting 1 year crossing leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(new Temporal.Duration(2), options), + 2019, 4, "M04", "Subtracting 2 years from common-year M04 crossing leap year lands in common-year M04", + undefined, undefined, null +); + +// Months + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months12 = new Temporal.Duration(0, -12); +const months12n = new Temporal.Duration(0, 12); +const months13 = new Temporal.Duration(0, -13); +const months13n = new Temporal.Duration(0, 13); + +const leap202003 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); +const leap202006 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M06", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1947, monthCode: "M02L", calendar }, options).subtract(months1), + 1947, 4, "M03", "add 1 month, starting at start of leap month", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1955, monthCode: "M03L", calendar }, options).subtract(months1), + 1955, 5, "M04", "add 1 month, starting at start of leap month with 30 days", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.subtract(months1), + 2020, 4, "M04", "adding 1 month to M03 in leap year lands in M04 (not M04L)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.subtract(new Temporal.Duration(0, -2)), + 2020, 5, "M04L", "adding 2 months to M03 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202003.subtract(new Temporal.Duration(0, -3)), + 2020, 6, "M05", "adding 3 months to M03 in leap year lands in M05 (not M06)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(months12), + 2020, 4, "M04", "Adding 12 months to common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(months13), + 2020, 5, "M04L", "Adding 13 months to common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(months12), + 2021, 3, "M03", "Adding 12 months to leap-year M04 lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(months13), + 2021, 4, "M04", "Adding 13 months to leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months12), + 2021, 4, "M04", "Adding 12 months to M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.subtract(new Temporal.Duration(-1, -12), options), + 2002, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.subtract(new Temporal.Duration(-2, -13), options), + 2004, 9, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(new Temporal.Duration(0, -24)), + 2021, 3, "M03", "Adding 24 months to common-year M04 crossing leap year with M04L, lands in common-year M03", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common201904.subtract(new Temporal.Duration(0, -25)), + 2021, 4, "M04", "Adding 25 months to common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.subtract(months1n), + 2020, 6, "M05", "Subtracting 1 month from M06 in leap year lands in M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.subtract(new Temporal.Duration(0, 2)), + 2020, 5, "M04L", "Subtracting 2 months from M06 in leap year lands in M04L (leap month)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202006.subtract(new Temporal.Duration(0, 3)), + 2020, 4, "M04", "Subtracting 3 months from M06 in leap year lands in M04 (not M03)", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M05", calendar }, options).subtract(months1n), + 2020, 5, "M04L", "Subtracting 1 month from M05 in leap year lands in M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months1n), + 2020, 4, "M04", "Subtracting 1 month from M04L in calendar lands in M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(months12n), + 2020, 5, "M04L", "Subtracting 12 months from common-year M04 lands in leap-year M04L", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(months13n), + 2020, 4, "M04", "Subtracting 13 months from common-year M04 lands in leap-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004.subtract(months12n), + 2019, 4, "M04", "Subtracting 12 months from leap-year M04 lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months12n), + 2019, 5, "M05", "Subtracting 12 months from M04L lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + leap202004L.subtract(months13n), + 2019, 4, "M04", "Subtracting 13 months from M04L lands in common-year M04", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200108.subtract(new Temporal.Duration(1, 12), options), + 1999, 8, "M08", "Adding 1y 12mo crossing leap month in the year part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common200008.subtract(new Temporal.Duration(2, 13), options), + 1997, 8, "M08", "Adding 1y 13mo crossing leap month in the months part", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(new Temporal.Duration(0, 24)), + 2019, 5, "M05", "Subtracting 24 months from common-year M04 crossing leap year with M04L, lands in common-year M05", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + common202104.subtract(new Temporal.Duration(0, 25)), + 2019, 4, "M04", "Subtracting 25 months from common-year M04 crossing leap year with M04L, lands in common-year M04", + undefined, undefined, null +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-hebrew.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-hebrew.js new file mode 100644 index 00000000000..668c36a4f5e --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-months-hebrew.js @@ -0,0 +1,339 @@ +// 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.plainyearmonth.prototype.subtract +description: Arithmetic around leap months in the hebrew calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "hebrew"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years2 = new Temporal.Duration(-2); +const years2n = new Temporal.Duration(2); + +const leap1AdarI = Temporal.PlainYearMonth.from({ year: 5782, monthCode: "M05L", calendar }, options); +const leap1AdarII = Temporal.PlainYearMonth.from({ year: 5782, monthCode: "M06", calendar }, options); +const common1Adar = Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M06", calendar }, options); +const common = Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M08", calendar }, options); +const leap2AdarI = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M05L", calendar }, options); +const leap2AdarII = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M06", calendar }, options); +const common2Adar = Temporal.PlainYearMonth.from({ year: 5785, monthCode: "M06", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.subtract(years1, options), + 5784, 7, "M06", "Adding 1 year to common-year Adar (M06) lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.subtract(years2, options), + 5785, 6, "M06", "Adding 2 years to common-year Adar (M06) crossing leap year lands in common-year Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(years1), + 5785, 6, "M06", "Adding 1 year to Adar I (M05L) lands in common-year Adar (M06) with constrain", + "am", 5785, null +); + +assert.throws(RangeError, function () { + leap2AdarI.subtract(years1, options); +}, "Adding 1 year to Adar I (M05L) rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.subtract(years1, options), + 5785, 6, "M06", "Adding 1 year to Adar II (M06) lands in common-year Adar (M06) even with reject", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + common.subtract(years1, options), + 5784, 9, "M08", "Adding 1 year across Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarI.subtract(years2, options), + 5784, 6, "M05L", "Adding 2 years to leap-year Adar I (M05L) lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarII.subtract(years2, options), + 5784, 7, "M06", "Adding 2 years to leap-year Adar II (M06) lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.subtract(years1n, options), + 5784, 7, "M06", "Subtracting 1 year from common-year Adar (M06) lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.subtract(years2n, options), + 5783, 6, "M06", "Subtracting 2 years from common-year Adar (M06) crossing leap year lands in common-year Adar (M06)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(years1n), + 5783, 6, "M06", "Subtracting 1 year from Adar I (M05L) lands in common-year Adar (M06) with constrain", + "am", 5783, null +); + +assert.throws(RangeError, function () { + leap2AdarI.subtract(years1n, options); +}, "Subtracting 1 year from Adar I (M05L) rejects"); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.subtract(years1n, options), + 5783, 6, "M06", "Subtracting 1 year from Adar II (M06) lands in common-year Adar (M06) even with reject", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common.subtract(years2n, options), + 5781, 8, "M08", "Subtracting 2 years across Adar I (M05L)", + "am", 5781, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(years2n, options), + 5782, 6, "M05L", "Subtracting 2 years from leap-year Adar I (M05L) lands in leap-year Adar I (M05L)", + "am", 5782, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.subtract(years2n, options), + 5782, 7, "M06", "Subtracting 2 years from leap-year Adar II (M06) lands in leap-year Adar II (M06)", + "am", 5782, null +); + +// Months + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months2 = new Temporal.Duration(0, -2); +const months2n = new Temporal.Duration(0, 2); +const months12 = new Temporal.Duration(0, -12); +const months12n = new Temporal.Duration(0, 12); +const months13 = new Temporal.Duration(0, -13); +const months13n = new Temporal.Duration(0, 13); +const months24 = new Temporal.Duration(0, -24); +const months24n = new Temporal.Duration(0, 24); + +const date1 = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M04", calendar }, options); +const date3 = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M07", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date1.subtract(months1, options), + 5784, 5, "M05", "Adding 1 month to M04 in leap year lands in M05 (Shevat)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.subtract(months2, options), + 5784, 6, "M05L", "Adding 2 months to M04 in leap year lands in M05L (Adar I)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.subtract(new Temporal.Duration(0, -3), options), + 5784, 7, "M06", "Adding 3 months to M04 in leap year lands in M06 (Adar II)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(months1, options), + 5784, 7, "M06", "Adding 1 month to M05L (Adar I) lands in M06 (Adar II)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M04", calendar }, options).subtract(months2, options), + 5783, 6, "M06", "Adding 2 months to M04 in non-leap year lands in M06 (no M05L)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.subtract(months12, options), + 5784, 6, "M05L", "Adding 12 months to common-year Adar lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.subtract(months13, options), + 5784, 7, "M06", "Adding 13 months to common-year Adar lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(months12, options), + 5785, 5, "M05", "Adding 12 months to leap-year Adar I lands in Shevat (M05)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(months13, options), + 5785, 6, "M06", "Adding 13 months to leap-year Adar I lands in Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.subtract(months12, options), + 5785, 6, "M06", "Adding 12 months to leap-year Adar II lands in Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + common.subtract(months13, options), + 5784, 9, "M08", "Adding 13 months across Adar I (M05L) lands in same month code", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common.subtract(new Temporal.Duration(-1, -12), options), + 5785, 8, "M08", "Adding 1y 12mo across Adar I (M05L) in the years part lands in same month code", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.subtract(new Temporal.Duration(-2, -13), options), + 5787, 8, "M07", "Adding 2y 13mo across Adar I (M05L) in the months part lands in same month code", + "am", 5787, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.subtract(months24, options), + 5785, 5, "M05", "Adding 24 months to common-year Adar crossing a leap year lands in common-year Shevat (M05)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + common1Adar.subtract(new Temporal.Duration(0, -25), options), + 5785, 6, "M06", "Adding 25 months to common-year Adar crossing a leap year lands in common-year Adar (M06)", + "am", 5785, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarI.subtract(months24, options), + 5784, 5, "M05", "Adding 24 months to leap-year Adar I lands in leap-year Shevat (M05)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap1AdarII.subtract(months24, options), + 5784, 6, "M05L", "Adding 24 months to leap-year Adar II lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.subtract(months1n, options), + 5784, 7, "M06", "Subtracting 1 month from M07 in leap year lands in M06 (Adar II)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.subtract(months2n, options), + 5784, 6, "M05L", "Subtracting 2 months from M07 in leap year lands in M05L (Adar I)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + date3.subtract(new Temporal.Duration(0, 3), options), + 5784, 5, "M05", "Subtracting 3 months from M07 in leap year lands in M05 (Shevat)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.subtract(months1n, options), + 5784, 6, "M05L", "Subtracting 1 month from M06 (Adar II) in leap year lands in M05L (Adar I)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(months1n, options), + 5784, 5, "M05", "Subtracting 1 month from M05L (Adar I) lands in M05 (Shevat)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5783, monthCode: "M07", calendar }).subtract(months2n, options), + 5783, 5, "M05", "Subtracting 2 months from M07 in non-leap year lands in M05 (no M05L)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.subtract(months12n, options), + 5784, 7, "M06", "Subtracting 12 months from common-year Adar lands in leap-year Adar II (M06)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.subtract(months13n, options), + 5784, 6, "M05L", "Subtracting 13 months from common-year Adar lands in leap-year Adar I (M05L)", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(months12n, options), + 5783, 6, "M06", "Subtracting 12 months from leap-year Adar I lands in Adar (M06)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(months13n, options), + 5783, 5, "M05", "Subtracting 13 months from leap-year Adar I lands in Shevat (M05)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.subtract(months12n, options), + 5783, 7, "M07", "Subtracting 12 months from leap-year Adar II lands in Nisan (M07)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.subtract(months24n, options), + 5783, 7, "M07", "Subtracting 24 months from common-year Adar crossing a leap year lands in common-year Nisan (M07)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.subtract(new Temporal.Duration(2, 12), options), + 5781, 4, "M04", "Subtracting 2y 12mo across Adar I (M05L) in the years part lands in same month code", + "am", 5781, null +); + +TemporalHelpers.assertPlainYearMonth( + date1.subtract(new Temporal.Duration(1, 13), options), + 5782, 4, "M04", "Subtracting 1y 13mo across Adar I (M05L) in the months part lands in same month code", + "am", 5782, null +); + +TemporalHelpers.assertPlainYearMonth( + common2Adar.subtract(new Temporal.Duration(0, 25), options), + 5783, 6, "M06", "Subtracting 25 months from common-year Adar crossing a leap year lands in common-year Adar (M06)", + "am", 5783, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarI.subtract(months24n, options), + 5782, 7, "M06", "Subtracting 24 months from leap-year Adar I lands in leap-year Adar (M06)", + "am", 5782, null +); + +TemporalHelpers.assertPlainYearMonth( + leap2AdarII.subtract(months24n, options), + 5782, 8, "M07", "Subtracting 24 months from leap-year Adar II lands in leap-year Nisan (M07)", + "am", 5782, null +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-buddhist.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-buddhist.js new file mode 100644 index 00000000000..5bf4b13f6ff --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-buddhist.js @@ -0,0 +1,97 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (buddhist calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "buddhist"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +const date256302 = Temporal.PlainYearMonth.from({ year: 2563, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date256302.subtract(years1, options), + 2564, 2, "M02", "add 1y to Feb", + "be", 2564); +TemporalHelpers.assertPlainYearMonth( + date256302.subtract(years4, options), + 2567, 2, "M02", "add 4y to Feb", + "be", 2567); + +TemporalHelpers.assertPlainYearMonth( + date256302.subtract(years1n, options), + 2562, 2, "M02", "subtract 1y from Feb", + "be", 2562); +TemporalHelpers.assertPlainYearMonth( + date256302.subtract(years4n, options), + 2559, 2, "M02", "subtract 4y from Feb", + "be", 2559); + +// Months + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months5 = new Temporal.Duration(0, -5); +const months11n = new Temporal.Duration(0, 11); +const years1months2 = new Temporal.Duration(-1, -2); +const years1months2n = new Temporal.Duration(1, 2); + +const date256301 = Temporal.PlainYearMonth.from({ year: 2563, monthCode: "M01", calendar }, options); +const date256303 = Temporal.PlainYearMonth.from({ year: 2563, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date256301.subtract(months1, options), + 2563, 2, "M02", "add 1mo to Jan in leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M09", calendar }, options).subtract(months5), + 2565, 2, "M02", "add 5mo with result in the next year", + "be", 2565); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2562, monthCode: "M09", calendar }, options).subtract(months5), + 2563, 2, "M02", "add 5mo with result in the next leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M12", calendar }, options).subtract(years1months2), + 2566, 2, "M02", "add 1y 2mo with result in the next year", + "be", 2566); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2565, monthCode: "M12", calendar }, options).subtract(years1months2), + 2567, 2, "M02", "add 1y 2mo with result in the next leap year", + "be", 2567); + +TemporalHelpers.assertPlainYearMonth( + date256303.subtract(months1n, options), + 2563, 2, "M02", "subtract 1mo from Mar in leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + date256301.subtract(months11n, options), + 2562, 2, "M02", "subtract 11mo with result in the previous year", + "be", 2562); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M01", calendar }, options).subtract(months11n, options), + 2563, 2, "M02", "add 11mo with result in the previous leap year", + "be", 2563); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2565, monthCode: "M04", calendar }, options).subtract(years1months2n), + 2564, 2, "M02", "add 1y 2mo with result in the previous year", + "be", 2564); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2564, monthCode: "M04", calendar }, options).subtract(years1months2n), + 2563, 2, "M02", "add 1y 2mo with result in the previous leap year", + "be", 2563); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-coptic.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-coptic.js new file mode 100644 index 00000000000..340d6cd8ab8 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-coptic.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (coptic calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "coptic"; +const options = { overflow: "reject" }; + +const leapDay = Temporal.PlainYearMonth.from({ year: 1739, monthCode: "M13", calendar }, options); + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1, options), + 1740, 13, "M13", "Adding 1 year to epagomenal month", + "am", 1740, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1n, options), + 1738, 13, "M13", "Subtracting 1 year from epagomenal month", + "am", 1738, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4, options), + 1743, 13, "M13", "Adding 4 years to epagomenal month", + "am", 1743, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4n, options), + 1735, 13, "M13", "Subtracting 4 years from epagomenal month", + "am", 1735, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethioaa.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethioaa.js new file mode 100644 index 00000000000..7b64a9b72f2 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethioaa.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (ethioaa calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "ethioaa"; +const options = { overflow: "reject" }; + +const leapDay = Temporal.PlainYearMonth.from({ year: 7515, monthCode: "M13", calendar }, options); + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1, options), + 7516, 13, "M13", "Adding 1 year to epagomenal month", + "aa", 7516, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1n, options), + 7514, 13, "M13", "Subtracting 1 year from epagomenal month", + "aa", 7514, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4, options), + 7519, 13, "M13", "Adding 4 years to epagomenal month", + "aa", 7519, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4n, options), + 7511, 13, "M13", "Subtracting 4 years from epagomenal month", + "aa", 7511, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethiopic.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethiopic.js new file mode 100644 index 00000000000..23b66523e57 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-ethiopic.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (ethiopic calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "ethiopic"; +const options = { overflow: "reject" }; + +const leapDay = Temporal.PlainYearMonth.from({ year: 2015, monthCode: "M13", calendar }, options); + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1, options), + 2016, 13, "M13", "Adding 1 year to leap day", + "am", 2016, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1n, options), + 2014, 13, "M13", "Subtracting 1 year from leap day", + "am", 2014, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4, options), + 2019, 13, "M13", "Adding 4 years to leap day", + "am", 2019, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4n, options), + 2011, 13, "M13", "Subtracting 4 years from leap day", + "am", 2011, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-gregory.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-gregory.js new file mode 100644 index 00000000000..2753ce0f94d --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-gregory.js @@ -0,0 +1,99 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (gregory calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "gregory"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +const date202002 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years1, options), + 2021, 2, "M02", "add 1y to leap day", + "ce", 2021); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years4, options), + 2024, 2, "M02", "add 4y to leap day", + "ce", 2024); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years1n, options), + 2019, 2, "M02", "subtract 1y from leap day", + "ce", 2019); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years4n, options), + 2016, 2, "M02", "subtract 4y from leap day", + "ce", 2016); + +// Months + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months5 = new Temporal.Duration(0, -5); +const months11n = new Temporal.Duration(0, 11); +const years1months2 = new Temporal.Duration(-1, -2); +const years1months2n = new Temporal.Duration(1, 2); + +const date202001 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M01", calendar }, options); +const date202003 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date202001.subtract(months1, options), + 2020, 2, "M02", "add 1mo to in leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M09", calendar }, options).subtract(months5), + 2022, 2, "M02", "add 5mo with result in the next year", + "ce", 2022); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M09", calendar }, options).subtract(months5), + 2020, 2, "M02", "add 5mo with result in the next leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M12", calendar }, options).subtract(years1months2), + 2023, 2, "M02", "add 1y 2mo with result in the next year", + "ce", 2023); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M12", calendar }, options).subtract(years1months2), + 2024, 2, "M02", "add 1y 2mo with result in the next leap year", + "ce", 2024); + +TemporalHelpers.assertPlainYearMonth( + date202003.subtract(months1n, options), + 2020, 2, "M02", "subtract 1mo from Mar in leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + date202001.subtract(months11n), + 2019, 2, "M02", "subtract 11mo with result in the previous year", + "ce", 2019); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M01", calendar }, options).subtract(months11n), + 2020, 2, "M02", "add 11mo with result in the previous leap year", + "ce", 2020); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M04", calendar }, options).subtract(years1months2n), + 2021, 2, "M02", "add 1y 2mo with result in the previous year", + "ce", 2021); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options).subtract(years1months2n), + 2020, 2, "M02", "add 1y 2mo with result in the previous leap year", + "ce", 2020); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-indian.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-indian.js new file mode 100644 index 00000000000..8d3b12141a9 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-indian.js @@ -0,0 +1,39 @@ +// 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.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (indian calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "indian"; +const options = { overflow: "reject" }; + +const leapDay = Temporal.PlainYearMonth.from({ year: 1946, monthCode: "M01", calendar }, options); + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1, options), + 1947, 1, "M01", "Adding 1 year to Chaitra", + "shaka", 1947, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years1n, options), + 1945, 1, "M01", "Subtracting 1 year from Chaitra", + "shaka", 1945, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4, options), + 1950, 1, "M01", "Adding 4 years to Chaitra", + "shaka", 1950, null); + +TemporalHelpers.assertPlainYearMonth( + leapDay.subtract(years4n, options), + 1942, 1, "M01", "Subtracting 4 years from Chaitra", + "shaka", 1942, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-civil.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-civil.js new file mode 100644 index 00000000000..7010020d839 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-civil.js @@ -0,0 +1,42 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (islamic-civil calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "islamic-civil"; +const options = { overflow: "reject" }; + +// Month 12 (Dhu al-Hijjah) has 29 days in common years and 30 in leap years. +// AH 1442, 1445, and 1447 are leap years. + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years2 = new Temporal.Duration(-2); +const years3n = new Temporal.Duration(3); + +const date144512 = Temporal.PlainYearMonth.from({ year: 1445, monthCode: "M12", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years1, options), + 1446, 12, "M12", "add 1y in leap year", + "ah", 1446, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years2, options), + 1447, 12, "M12", "add 2y landing in next leap year", + "ah", 1447, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years1n, options), + 1444, 12, "M12", "subtract 1y in leap year", + "ah", 1444, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years3n, options), + 1442, 12, "M12", "subtract 3y landing in previous leap year", + "ah", 1442, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-tbla.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-tbla.js new file mode 100644 index 00000000000..92e8b9227bf --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-islamic-tbla.js @@ -0,0 +1,42 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (islamic-tbla calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "islamic-tbla"; +const options = { overflow: "reject" }; + +// Month 12 (Dhu al-Hijjah) has 29 days in common years and 30 in leap years. +// AH 1442, 1445, and 1447 are leap years. + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years2 = new Temporal.Duration(-2); +const years3n = new Temporal.Duration(3); + +const date144512 = Temporal.PlainYearMonth.from({ year: 1445, monthCode: "M12", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years1, options), + 1446, 12, "M12", "add 1y in leap year", + "ah", 1446, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years2, options), + 1447, 12, "M12", "add 2y landing in next leap year", + "ah", 1447, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years1n, options), + 1444, 12, "M12", "subtract 1y in leap year", + "ah", 1444, null); + +TemporalHelpers.assertPlainYearMonth( + date144512.subtract(years3n, options), + 1442, 12, "M12", "subtract 3y landing in previous leap year", + "ah", 1442, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-japanese.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-japanese.js new file mode 100644 index 00000000000..d36bd6a80b1 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-japanese.js @@ -0,0 +1,99 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (japanese calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "japanese"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +const date202002 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years1, options), + 2021, 2, "M02", "add 1y to Feb", + "reiwa", 3); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years4, options), + 2024, 2, "M02", "add 4y to Feb", + "reiwa", 6); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years1n, options), + 2019, 2, "M02", "subtract 1y from Feb", + "heisei", 31); + +TemporalHelpers.assertPlainYearMonth( + date202002.subtract(years4n, options), + 2016, 2, "M02", "subtract 4y from Feb", + "heisei", 28); + +// Months + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months5 = new Temporal.Duration(0, -5); +const months11n = new Temporal.Duration(0, 11); +const years1months2 = new Temporal.Duration(-1, -2); +const years1months2n = new Temporal.Duration(1, 2); + +const date202001 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M01", calendar }, options); +const date202003 = Temporal.PlainYearMonth.from({ year: 2020, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date202001.subtract(months1, options), + 2020, 2, "M02", "add 1mo to Jan", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M09", calendar }, options).subtract(months5), + 2022, 2, "M02", "add 5mo with result in the next year", + "reiwa", 4); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2019, monthCode: "M09", calendar }, options).subtract(months5), + 2020, 2, "M02", "add 5mo with result in the next leap year", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M12", calendar }, options).subtract(years1months2), + 2023, 2, "M02", "add 1y 2mo with result in the next year", + "reiwa", 5); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M12", calendar }, options).subtract(years1months2), + 2024, 2, "M02", "add 1y 2mo with result in the next leap year", + "reiwa", 6); + +TemporalHelpers.assertPlainYearMonth( + date202003.subtract(months1n, options), + 2020, 2, "M02", "subtract 1mo from Mar", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + date202001.subtract(months11n, options), + 2019, 2, "M02", "subtract 11mo with result in the previous year", + "heisei", 31); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M01", calendar }, options).subtract(months11n, options), + 2020, 2, "M02", "add 11mo with result in the previous leap year", + "reiwa", 2); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2022, monthCode: "M04", calendar }, options).subtract(years1months2n, options), + 2021, 2, "M02", "add 1y 2mo with result in the previous year", + "reiwa", 3); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M04", calendar }, options).subtract(years1months2n, options), + 2020, 2, "M02", "add 1y 2mo with result in the previous leap year", + "reiwa", 2); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-persian.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-persian.js new file mode 100644 index 00000000000..5fa5c24739c --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-persian.js @@ -0,0 +1,90 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (Persian calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "persian"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +const date136212 = Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M12", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date136212.subtract(years1, options), + 1363, 12, "M12", "add 1y in leap year", + "ap", 1363, null); + +TemporalHelpers.assertPlainYearMonth( + date136212.subtract(years4, options), + 1366, 12, "M12", "add 4y in leap year", + "ap", 1366, null); + +TemporalHelpers.assertPlainYearMonth( + date136212.subtract(years1n, options), + 1361, 12, "M12", "subtract 1y in leap year", + "ap", 1361, null); + +TemporalHelpers.assertPlainYearMonth( + date136212.subtract(years4n, options), + 1358, 12, "M12", "subtract 4y in leap year", + "ap", 1358, null); + +// Months + +const months1n = new Temporal.Duration(0, 1); +const months6 = new Temporal.Duration(0, -6); +const months11n = new Temporal.Duration(0, 11); +const years1months2 = new Temporal.Duration(-1, -2); +const years1months2n = new Temporal.Duration(1, 2); + +const date136206 = Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M06", calendar }, options); +const date136211 = Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M11", calendar }, options); +const date136301 = Temporal.PlainYearMonth.from({ year: 1363, monthCode: "M01", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date136206.subtract(months6, options), + 1362, 12, "M12", "add 6mo to Shahrivar in leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1362, monthCode: "M10", calendar }, options).subtract(years1months2, options), + 1363, 12, "M12", "add 1y 2mo with result in the next year", + "ap", 1363, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1361, monthCode: "M10", calendar }, options).subtract(years1months2), + 1362, 12, "M12", "add 1y 2mo with result in the next leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + date136301.subtract(months1n, options), + 1362, 12, "M12", "subtract 1mo from Farvardin in leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + date136211.subtract(months11n, options), + 1361, 12, "M12", "subtract 11mo with result in the previous year", + "ap", 1361, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1363, monthCode: "M11", calendar }, options).subtract(months11n, options), + 1362, 12, "M12", "subtract 11mo with result in the previous leap year", + "ap", 1362, null); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1364, monthCode: "M02", calendar }, options).subtract(years1months2n, options), + 1362, 12, "M12", "add 1y 2mo with result in the previous year", + "ap", 1362, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 1365, monthCode: "M02", calendar }, options).subtract(years1months2n, options), + 1363, 12, "M12", "add 1y 2mo with result in the previous leap year", + "ap", 1363, null); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-roc.js b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-roc.js new file mode 100644 index 00000000000..2f378b2a48f --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/subtract/leap-year-roc.js @@ -0,0 +1,99 @@ +// Copyright (C) 2025 Igalia, S.L., and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Check various basic calculations involving leap years (roc calendar) +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "roc"; +const options = { overflow: "reject" }; + +// Years + +const years1 = new Temporal.Duration(-1); +const years1n = new Temporal.Duration(1); +const years4 = new Temporal.Duration(-4); +const years4n = new Temporal.Duration(4); + +const date10902 = Temporal.PlainYearMonth.from({ year: 109, monthCode: "M02", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date10902.subtract(years1), + 110, 2, "M02", "add 1y in leap year", + "roc", 110); + +TemporalHelpers.assertPlainYearMonth( + date10902.subtract(years4, options), + 113, 2, "M02", "add 4y in leap year", + "roc", 113); + +TemporalHelpers.assertPlainYearMonth( + date10902.subtract(years1n), + 108, 2, "M02", "subtract 1y in leap year", + "roc", 108); + +TemporalHelpers.assertPlainYearMonth( + date10902.subtract(years4n, options), + 105, 2, "M02", "subtract 4y in leap year", + "roc", 105); + +// Months + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months5 = new Temporal.Duration(0, -5); +const months11n = new Temporal.Duration(0, 11); +const years1months2 = new Temporal.Duration(-1, -2); +const years1months2n = new Temporal.Duration(1, 2); + +const date10901 = Temporal.PlainYearMonth.from({ year: 109, monthCode: "M01", calendar }, options); +const date10903 = Temporal.PlainYearMonth.from({ year: 109, monthCode: "M03", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + date10901.subtract(months1, options), + 109, 2, "M02", "add 1mo to Jan in leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M09", calendar }, options).subtract(months5, options), + 111, 2, "M02", "add 5mo with result in the next year", + "roc", 111); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 108, monthCode: "M09", calendar }, options).subtract(months5, options), + 109, 2, "M02", "add 5mo with result in the next leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M12", calendar }, options).subtract(years1months2, options), + 112, 2, "M02", "add 1y 2mo with result in the next year", + "roc", 112); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 111, monthCode: "M12", calendar }, options).subtract(years1months2, options), + 113, 2, "M02", "add 1y 2mo with result in the next leap year", + "roc", 113); + +TemporalHelpers.assertPlainYearMonth( + date10903.subtract(months1n, options), + 109, 2, "M02", "subtract 1mo from Mar in leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + date10901.subtract(months11n, options), + 108, 2, "M02", "subtract 11mo with result in the previous year", + "roc", 108); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M01", calendar }, options).subtract(months11n, options), + 109, 2, "M02", "add 11mo with result in the previous leap year", + "roc", 109); + +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 111, monthCode: "M04", calendar }, options).subtract(years1months2n, options), + 110, 2, "M02", "add 1y 2mo with result in the previous year", + "roc", 110); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 110, monthCode: "M04", calendar }, options).subtract(years1months2n, options), + 109, 2, "M02", "add 1y 2mo with result in the previous leap year", + "roc", 109);