From 8cb018e805d6ce89cca92c4c160bc1e37e7e29c3 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 21 Nov 2025 12:56:59 -0800 Subject: [PATCH] Intl Era Monthcode: Split out and expand end-of-month tests These end-of-month tests were moved in from staging in https://github.com/tc39/test262/pull/4667. Split them out into their own files and expand to cover PlainDateTime and ZonedDateTime as well. --- .../PlainDate/prototype/add/basic-chinese.js | 52 ------------- .../PlainDate/prototype/add/basic-dangi.js | 52 ------------- .../prototype/add/month-boundary-chinese.js | 77 +++++++++++++++++++ .../prototype/add/month-boundary-dangi.js | 77 +++++++++++++++++++ .../prototype/subtract/basic-chinese.js | 52 ------------- .../prototype/subtract/basic-dangi.js | 52 ------------- .../subtract/month-boundary-chinese.js | 77 +++++++++++++++++++ .../subtract/month-boundary-dangi.js | 77 +++++++++++++++++++ .../prototype/add/month-boundary-chinese.js | 77 +++++++++++++++++++ .../prototype/add/month-boundary-dangi.js | 77 +++++++++++++++++++ .../subtract/month-boundary-chinese.js | 77 +++++++++++++++++++ .../subtract/month-boundary-dangi.js | 77 +++++++++++++++++++ .../prototype/add/month-boundary-chinese.js | 77 +++++++++++++++++++ .../prototype/add/month-boundary-dangi.js | 77 +++++++++++++++++++ .../subtract/month-boundary-chinese.js | 77 +++++++++++++++++++ .../subtract/month-boundary-dangi.js | 77 +++++++++++++++++++ 16 files changed, 924 insertions(+), 208 deletions(-) create mode 100644 test/intl402/Temporal/PlainDate/prototype/add/month-boundary-chinese.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/add/month-boundary-dangi.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-chinese.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-dangi.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-chinese.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-dangi.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-chinese.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-dangi.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-chinese.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-dangi.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-chinese.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-dangi.js diff --git a/test/intl402/Temporal/PlainDate/prototype/add/basic-chinese.js b/test/intl402/Temporal/PlainDate/prototype/add/basic-chinese.js index b4627387ff..800acd2112 100644 --- a/test/intl402/Temporal/PlainDate/prototype/add/basic-chinese.js +++ b/test/intl402/Temporal/PlainDate/prototype/add/basic-chinese.js @@ -82,27 +82,12 @@ const months4 = new Temporal.Duration(0, 4); const months4n = new Temporal.Duration(0, -4); const months6 = new Temporal.Duration(0, 6); const months6n = new Temporal.Duration(0, -6); -const durations = [ - months1, - months1n, - months4, - months4n, - months6, - months6n, -]; const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); -const dates = [ - date201901, - date201906, - date201911, - date201912, - date200012 -]; TemporalHelpers.assertPlainDate( date201911.add(months1), @@ -154,43 +139,6 @@ TemporalHelpers.assertPlainDate( 2000, 6, "M06", 1, "Subtracting 6 months, with result in same year" ); -for (var duration of durations) { - for (var start of dates) { - const end = start.add(duration); - - // startYesterday = start - (1 day) - const startYesterday = start.add({ days: -1 }); - // endYesterday = startYesterday + duration - const endYesterday = startYesterday.add(duration); - // When adding months, the result day should be the same - // unless there are fewer days in the destination month than the source day - assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); - - // endYesterdayNextDay = endYesterday + (1 day) - var endYesterdayNextDay = endYesterday.add({ days: 1 }); - // Move forward to next first-day-of-month - while (endYesterdayNextDay.day !== 1) { - endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); - } - - TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); - - // endReverse should equal end - const endReverse = endYesterdayNextDay.add({ days: -1 }); - const startReverse = endReverse.add(duration.negated()); - // subtracting months give the same day unless there are fewer days in the destination month - assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); - - // Move forward to next first-day-of-month - var startReverseNextDay = startReverse.add({ days: 1 }); - while(startReverseNextDay.day !== 1) { - startReverseNextDay = startReverseNextDay.add({ days: 1 }); - } - - TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); - } -} - // Weeks const months2weeks3 = new Temporal.Duration(0, /* months = */ 2, /* weeks = */ 3); diff --git a/test/intl402/Temporal/PlainDate/prototype/add/basic-dangi.js b/test/intl402/Temporal/PlainDate/prototype/add/basic-dangi.js index e2b0692d9e..6c75c118d5 100644 --- a/test/intl402/Temporal/PlainDate/prototype/add/basic-dangi.js +++ b/test/intl402/Temporal/PlainDate/prototype/add/basic-dangi.js @@ -82,27 +82,12 @@ const months4 = new Temporal.Duration(0, 4); const months4n = new Temporal.Duration(0, -4); const months6 = new Temporal.Duration(0, 6); const months6n = new Temporal.Duration(0, -6); -const durations = [ - months1, - months1n, - months4, - months4n, - months6, - months6n, -]; const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); -const dates = [ - date201901, - date201906, - date201911, - date201912, - date200012 -]; TemporalHelpers.assertPlainDate( date201911.add(months1), @@ -154,43 +139,6 @@ TemporalHelpers.assertPlainDate( 2000, 6, "M06", 1, "Subtracting 6 months, with result in same year" ); -for (var duration of durations) { - for (var start of dates) { - const end = start.add(duration); - - // startYesterday = start - (1 day) - const startYesterday = start.add({ days: -1 }); - // endYesterday = startYesterday + duration - const endYesterday = startYesterday.add(duration); - // When adding months, the result day should be the same - // unless there are fewer days in the destination month than the source day - assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); - - // endYesterdayNextDay = endYesterday + (1 day) - var endYesterdayNextDay = endYesterday.add({ days: 1 }); - // Move forward to next first-day-of-month - while (endYesterdayNextDay.day !== 1) { - endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); - } - - TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); - - // endReverse should equal end - const endReverse = endYesterdayNextDay.add({ days: -1 }); - const startReverse = endReverse.add(duration.negated()); - // subtracting months give the same day unless there are fewer days in the destination month - assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); - - // Move forward to next first-day-of-month - var startReverseNextDay = startReverse.add({ days: 1 }); - while(startReverseNextDay.day !== 1) { - startReverseNextDay = startReverseNextDay.add({ days: 1 }); - } - - TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); - } -} - // Weeks const months2weeks3 = new Temporal.Duration(0, /* months = */ 2, /* weeks = */ 3); diff --git a/test/intl402/Temporal/PlainDate/prototype/add/month-boundary-chinese.js b/test/intl402/Temporal/PlainDate/prototype/add/month-boundary-chinese.js new file mode 100644 index 0000000000..0920e8df67 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/add/month-boundary-chinese.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.add +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months4 = new Temporal.Duration(0, 4); +const months4n = new Temporal.Duration(0, -4); +const months6 = new Temporal.Duration(0, 6); +const months6n = new Temporal.Duration(0, -6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); +const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); +const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); +const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); +const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.add(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.add({ days: -1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.add(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.add({ days: 1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.add({ days: -1 }); + const startReverse = endReverse.add(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.add({ days: 1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/PlainDate/prototype/add/month-boundary-dangi.js b/test/intl402/Temporal/PlainDate/prototype/add/month-boundary-dangi.js new file mode 100644 index 0000000000..a3fa860f12 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/add/month-boundary-dangi.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.add +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months4 = new Temporal.Duration(0, 4); +const months4n = new Temporal.Duration(0, -4); +const months6 = new Temporal.Duration(0, 6); +const months6n = new Temporal.Duration(0, -6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); +const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); +const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); +const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); +const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.add(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.add({ days: -1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.add(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.add({ days: 1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.add({ days: -1 }); + const startReverse = endReverse.add(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.add({ days: 1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/PlainDate/prototype/subtract/basic-chinese.js b/test/intl402/Temporal/PlainDate/prototype/subtract/basic-chinese.js index 2a9b02732a..81c4aacb29 100644 --- a/test/intl402/Temporal/PlainDate/prototype/subtract/basic-chinese.js +++ b/test/intl402/Temporal/PlainDate/prototype/subtract/basic-chinese.js @@ -82,27 +82,12 @@ const months4 = new Temporal.Duration(0, -4); const months4n = new Temporal.Duration(0, 4); const months6 = new Temporal.Duration(0, -6); const months6n = new Temporal.Duration(0, 6); -const durations = [ - months1, - months1n, - months4, - months4n, - months6, - months6n, -]; const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); -const dates = [ - date201901, - date201906, - date201911, - date201912, - date200012 -]; TemporalHelpers.assertPlainDate( date201911.subtract(months1), @@ -154,43 +139,6 @@ TemporalHelpers.assertPlainDate( 2000, 6, "M06", 1, "Subtracting 6 months, with result in same year" ); -for (var duration of durations) { - for (var start of dates) { - const end = start.subtract(duration.negated()); - - // startYesterday = start - (1 day) - const startYesterday = start.subtract({ days: 1 }); - // endYesterday = startYesterday + duration - const endYesterday = startYesterday.subtract(duration.negated()); - // When adding months, the result day should be the same - // unless there are fewer days in the destination month than the source day - assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); - - // endYesterdayNextDay = endYesterday + (1 day) - var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); - // Move forward to next first-day-of-month - while (endYesterdayNextDay.day !== 1) { - endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); - } - - TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); - - // endReverse should equal end - const endReverse = endYesterdayNextDay.subtract({ days: 1 }); - const startReverse = endReverse.subtract(duration); - // subtracting months give the same day unless there are fewer days in the destination month - assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); - - // Move forward to next first-day-of-month - var startReverseNextDay = startReverse.subtract({ days: -1 }); - while(startReverseNextDay.day !== 1) { - startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); - } - - TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); - } -} - // Weeks const months2weeks3 = new Temporal.Duration(0, /* months = */ -2, /* weeks = */ -3); diff --git a/test/intl402/Temporal/PlainDate/prototype/subtract/basic-dangi.js b/test/intl402/Temporal/PlainDate/prototype/subtract/basic-dangi.js index 421b20db71..a1d0497d58 100644 --- a/test/intl402/Temporal/PlainDate/prototype/subtract/basic-dangi.js +++ b/test/intl402/Temporal/PlainDate/prototype/subtract/basic-dangi.js @@ -82,27 +82,12 @@ const months4 = new Temporal.Duration(0, -4); const months4n = new Temporal.Duration(0, 4); const months6 = new Temporal.Duration(0, -6); const months6n = new Temporal.Duration(0, 6); -const durations = [ - months1, - months1n, - months4, - months4n, - months6, - months6n, -]; const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); -const dates = [ - date201901, - date201906, - date201911, - date201912, - date200012 -]; TemporalHelpers.assertPlainDate( date201911.subtract(months1), @@ -154,43 +139,6 @@ TemporalHelpers.assertPlainDate( 2000, 6, "M06", 1, "Subtracting 6 months, with result in same year" ); -for (var duration of durations) { - for (var start of dates) { - const end = start.subtract(duration); - - // startYesterday = start - (1 day) - const startYesterday = start.subtract({ days: 1 }); - // endYesterday = startYesterday + duration - const endYesterday = startYesterday.subtract(duration); - // When adding months, the result day should be the same - // unless there are fewer days in the destination month than the source day - assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); - - // endYesterdayNextDay = endYesterday + (1 day) - var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); - // Move forward to next first-day-of-month - while (endYesterdayNextDay.day !== 1) { - endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); - } - - TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); - - // endReverse should equal end - const endReverse = endYesterdayNextDay.subtract({ days: 1 }); - const startReverse = endReverse.subtract(duration); - // subtracting months give the same day unless there are fewer days in the destination month - assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); - - // Move forward to next first-day-of-month - var startReverseNextDay = startReverse.subtract({ days: -1 }); - while(startReverseNextDay.day !== 1) { - startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); - } - - TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); - } -} - // Weeks const months2weeks3 = new Temporal.Duration(0, /* months = */ -2, /* weeks = */ -3); diff --git a/test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-chinese.js b/test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-chinese.js new file mode 100644 index 0000000000..543abe0a7f --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-chinese.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.subtract +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months4 = new Temporal.Duration(0, -4); +const months4n = new Temporal.Duration(0, 4); +const months6 = new Temporal.Duration(0, -6); +const months6n = new Temporal.Duration(0, 6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); +const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); +const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); +const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); +const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.subtract(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.subtract({ days: 1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.subtract(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.subtract({ days: 1 }); + const startReverse = endReverse.subtract(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.subtract({ days: -1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-dangi.js b/test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-dangi.js new file mode 100644 index 0000000000..2b7621fd9a --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/subtract/month-boundary-dangi.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.subtract +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months4 = new Temporal.Duration(0, -4); +const months4n = new Temporal.Duration(0, 4); +const months6 = new Temporal.Duration(0, -6); +const months6n = new Temporal.Duration(0, 6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDate.from({ year: 2019, monthCode: "M01", day: 1, calendar }, options); +const date201906 = Temporal.PlainDate.from({ year: 2019, monthCode: "M06", day: 1, calendar }, options); +const date201911 = Temporal.PlainDate.from({ year: 2019, monthCode: "M11", day: 1, calendar }, options); +const date201912 = Temporal.PlainDate.from({ year: 2019, monthCode: "M12", day: 1, calendar }, options); +const date200012 = Temporal.PlainDate.from({ year: 2000, monthCode: "M12", day: 1, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.subtract(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.subtract({ days: 1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.subtract(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDate(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.subtract({ days: 1 }); + const startReverse = endReverse.subtract(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.subtract({ days: -1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDate(startReverseNextDay, start.year, start.month, start.monthCode, start.day, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-chinese.js b/test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-chinese.js new file mode 100644 index 0000000000..298b9ed850 --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-chinese.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.add +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months4 = new Temporal.Duration(0, 4); +const months4n = new Temporal.Duration(0, -4); +const months6 = new Temporal.Duration(0, 6); +const months6n = new Temporal.Duration(0, -6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, calendar }, options); +const date201906 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const date201911 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, calendar }, options); +const date201912 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const date200012 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.add(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.add({ days: -1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.add(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.add({ days: 1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.add({ days: -1 }); + const startReverse = endReverse.add(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.add({ days: 1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay, start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-dangi.js b/test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-dangi.js new file mode 100644 index 0000000000..e3aedd3ffc --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/add/month-boundary-dangi.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.add +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months4 = new Temporal.Duration(0, 4); +const months4n = new Temporal.Duration(0, -4); +const months6 = new Temporal.Duration(0, 6); +const months6n = new Temporal.Duration(0, -6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, calendar }, options); +const date201906 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const date201911 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, calendar }, options); +const date201912 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const date200012 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.add(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.add({ days: -1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.add(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.add({ days: 1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.add({ days: -1 }); + const startReverse = endReverse.add(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.add({ days: 1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay, start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-chinese.js b/test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-chinese.js new file mode 100644 index 0000000000..9cc84c3c0f --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-chinese.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.subtract +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months4 = new Temporal.Duration(0, -4); +const months4n = new Temporal.Duration(0, 4); +const months6 = new Temporal.Duration(0, -6); +const months6n = new Temporal.Duration(0, 6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, calendar }, options); +const date201906 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const date201911 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, calendar }, options); +const date201912 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const date200012 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.subtract(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.subtract({ days: 1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.subtract(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.subtract({ days: 1 }); + const startReverse = endReverse.subtract(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.subtract({ days: -1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay, start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-dangi.js b/test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-dangi.js new file mode 100644 index 0000000000..15837eb8df --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/subtract/month-boundary-dangi.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.subtract +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months4 = new Temporal.Duration(0, -4); +const months4n = new Temporal.Duration(0, 4); +const months6 = new Temporal.Duration(0, -6); +const months6n = new Temporal.Duration(0, 6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, calendar }, options); +const date201906 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, calendar }, options); +const date201911 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, calendar }, options); +const date201912 = Temporal.PlainDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const date200012 = Temporal.PlainDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.subtract(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.subtract({ days: 1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.subtract(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay, end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.subtract({ days: 1 }); + const startReverse = endReverse.subtract(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.subtract({ days: -1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay, start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-chinese.js b/test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-chinese.js new file mode 100644 index 0000000000..bdaa25a32c --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-chinese.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.add +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months4 = new Temporal.Duration(0, 4); +const months4n = new Temporal.Duration(0, -4); +const months6 = new Temporal.Duration(0, 6); +const months6n = new Temporal.Duration(0, -6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201906 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201911 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201912 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date200012 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.add(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.add({ days: -1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.add(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.add({ days: 1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay.toPlainDateTime(), end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.add({ days: -1 }); + const startReverse = endReverse.add(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.add({ days: 1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay.toPlainDateTime(), start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-dangi.js b/test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-dangi.js new file mode 100644 index 0000000000..062bed5548 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/add/month-boundary-dangi.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.add +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, 1); +const months1n = new Temporal.Duration(0, -1); +const months4 = new Temporal.Duration(0, 4); +const months4n = new Temporal.Duration(0, -4); +const months6 = new Temporal.Duration(0, 6); +const months6n = new Temporal.Duration(0, -6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201906 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201911 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201912 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date200012 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.add(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.add({ days: -1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.add(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.add({ days: 1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay.toPlainDateTime(), end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.add({ days: -1 }); + const startReverse = endReverse.add(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.add({ days: 1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.add({ days: 1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay.toPlainDateTime(), start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-chinese.js b/test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-chinese.js new file mode 100644 index 0000000000..e671772b74 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-chinese.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.subtract +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months4 = new Temporal.Duration(0, -4); +const months4n = new Temporal.Duration(0, 4); +const months6 = new Temporal.Duration(0, -6); +const months6n = new Temporal.Duration(0, 6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201906 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201911 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201912 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date200012 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.subtract(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.subtract({ days: 1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.subtract(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay.toPlainDateTime(), end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.subtract({ days: 1 }); + const startReverse = endReverse.subtract(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.subtract({ days: -1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay.toPlainDateTime(), start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-dangi.js b/test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-dangi.js new file mode 100644 index 0000000000..4cc2e16b22 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/subtract/month-boundary-dangi.js @@ -0,0 +1,77 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.subtract +description: Addition around end of month in the chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +const months1 = new Temporal.Duration(0, -1); +const months1n = new Temporal.Duration(0, 1); +const months4 = new Temporal.Duration(0, -4); +const months4n = new Temporal.Duration(0, 4); +const months6 = new Temporal.Duration(0, -6); +const months6n = new Temporal.Duration(0, 6); +const durations = [ + months1, + months1n, + months4, + months4n, + months6, + months6n, +]; + +const date201901 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M01", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201906 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M06", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201911 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M11", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date201912 = Temporal.ZonedDateTime.from({ year: 2019, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const date200012 = Temporal.ZonedDateTime.from({ year: 2000, monthCode: "M12", day: 1, hour: 12, minute: 34, timeZone: "UTC", calendar }, options); +const dates = [ + date201901, + date201906, + date201911, + date201912, + date200012, +]; + +for (var duration of durations) { + for (var start of dates) { + const end = start.subtract(duration); + + // startYesterday = start - (1 day) + const startYesterday = start.subtract({ days: 1 }); + // endYesterday = startYesterday + duration + const endYesterday = startYesterday.subtract(duration); + // When adding months, the result day should be the same + // unless there are fewer days in the destination month than the source day + assert.sameValue(endYesterday.day, Math.min(startYesterday.day, endYesterday.daysInMonth), "adding months should result in same day"); + + // endYesterdayNextDay = endYesterday + (1 day) + var endYesterdayNextDay = endYesterday.subtract({ days: -1 }); + // Move forward to next first-day-of-month + while (endYesterdayNextDay.day !== 1) { + endYesterdayNextDay = endYesterdayNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(endYesterdayNextDay.toPlainDateTime(), end.year, end.month, end.monthCode, end.day, 12, 34, 0, 0, 0, 0, `endYesterdayNextDay`, end.era, end.eraYear); + + // endReverse should equal end + const endReverse = endYesterdayNextDay.subtract({ days: 1 }); + const startReverse = endReverse.subtract(duration.negated()); + // subtracting months give the same day unless there are fewer days in the destination month + assert.sameValue(startReverse.day, Math.min(endReverse.day, startReverse.daysInMonth)); + + // Move forward to next first-day-of-month + var startReverseNextDay = startReverse.subtract({ days: -1 }); + while(startReverseNextDay.day !== 1) { + startReverseNextDay = startReverseNextDay.subtract({ days: -1 }); + } + + TemporalHelpers.assertPlainDateTime(startReverseNextDay.toPlainDateTime(), start.year, start.month, start.monthCode, start.day, 12, 34, 0, 0, 0, 0, `startReverseNextDay`, start.era, start.eraYear); + } +}