Intl Era Monthcode: Test constraining day in islamic-umalqura calendar

Similar to https://github.com/tc39/test262/pull/4700 but this is for an
observational Hijri calendar, not a tabular one. Any month may have
either 29 or 30 days in any year. So we additionally test adding or
subtracting 1 year from day 30 of a month, and landing in a year where
that month has 29 days.

Observational month lengths are provided in a comment for convenience.
This commit is contained in:
Philip Chimento 2025-11-24 12:57:40 -08:00 committed by Ms2ger
parent 74480890c3
commit 0fa672f26e
9 changed files with 2130 additions and 96 deletions

View File

@ -11,30 +11,282 @@ features: [Temporal, Intl.Era-monthcode]
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
const years1 = new Temporal.Duration(/* years = */ 1);
const years1n = new Temporal.Duration(-1);
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.PlainDate.from({ year: 1443, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1443.add(years1n),
1442, Number(monthCode.slice(1)), monthCode, 29, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.add(years1n, options);
}, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.PlainDate.from({ year: 1442, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1442.add(years1),
1443, Number(monthCode.slice(1)), monthCode, 29, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.add(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.PlainDate.from({ year: 1443, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1443.add(years1),
1444, Number(monthCode.slice(1)), monthCode, 29, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.add(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.PlainDate.from({ year: 1444, monthCode: "M10", day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1444.add(years1n),
1443, 10, "M10", 29, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.add(years1n, options);
}, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const months1 = new Temporal.Duration(0, /* months = */ 1);
const months3 = new Temporal.Duration(0, 3);
const months5 = new Temporal.Duration(0, 5);
const months7 = new Temporal.Duration(0, 7);
const months8 = new Temporal.Duration(0, 8);
const months9 = new Temporal.Duration(0, 9);
const months10 = new Temporal.Duration(0, 10);
const months1n = new Temporal.Duration(0, -1);
const months3n = new Temporal.Duration(0, -3);
const months4n = new Temporal.Duration(0, -4);
const months6n = new Temporal.Duration(0, -6);
const months8n = new Temporal.Duration(0, -8);
const months10n = new Temporal.Duration(0, -10);
const date1 = Temporal.PlainDate.from({ year: 1447, monthCode: "M01", day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1.add(months1),
1447, 2, "M02", 29, "Day is constrained when adding months to a 30-day month and landing in a 29-day month",
"ah", 1447
);
const date14420230 = Temporal.PlainDate.from({ year: 1442, monthCode: "M02", day: 30, calendar }, options);
const date14430130 = Temporal.PlainDate.from({ year: 1443, monthCode: "M01", day: 30, calendar }, options);
const date14440230 = Temporal.PlainDate.from({ year: 1444, monthCode: "M02", day: 30, calendar} , options);
const date14421130 = Temporal.PlainDate.from({ year: 1442, monthCode: "M11", day: 30, calendar }, options);
const date14431230 = Temporal.PlainDate.from({ year: 1443, monthCode: "M12", day: 30, calendar }, options);
const date14441230 = Temporal.PlainDate.from({ year: 1444, monthCode: "M12", day: 30, calendar} , options);
assert.throws(RangeError, function () {
date1.add(months1, options);
}, "Adding months to a 30-day month and landing in a 29-day month rejects");
// Forwards
TemporalHelpers.assertPlainDate(
date1.add(months1n),
1446, 12, "M12", 29, "Day is constrained when subtracting months from a 30-day month and landing in a 29-day month",
"ah", 1446
);
date14431230.add(months1),
1444, 1, "M01", 29, "29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date1.add(months1n, options);
}, "Subtracting months from a 30-day month and landing in a 29-day month rejects");
date14431230.add(months4n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.add(months1),
1443, 2, "M02", 29, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months1, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.add(months1),
1442, 3, "M03", 29, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months1, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.add(months3),
1443, 4, "M04", 29, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months3, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.add(months3),
1442, 5, "M05", 29, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months3, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.add(months5),
1443, 6, "M06", 29, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months5, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.add(months5),
1442, 7, "M07", 29, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months5, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.add(months7),
1443, 8, "M08", 29, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months7, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDate(
date14440230.add(months7),
1444, 9, "M09", 29, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.add(months7, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.add(months8),
1442, 10, "M10", 29, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months8, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14440230.add(months9),
1444, 11, "M11", 29, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.add(months9, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.add(months10),
1442, 12, "M12", 29, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months10, options);
}, "29-day Dhu al-Hijjah rejects with 30");
// Backwards
TemporalHelpers.assertPlainDate(
date14421130.add(months10n),
1442, 1, "M01", 29, "29-day Muharram constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months10n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.add(months10n),
1443, 2, "M02", 29, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months10n, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.add(months8n),
1442, 3, "M03", 29, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months8n, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.add(months8n),
1443, 4, "M04", 29, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months8n, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.add(months6n),
1442, 5, "M05", 29, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months6n, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.add(months6n),
1443, 6, "M06", 29, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months6n, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.add(months4n),
1442, 7, "M07", 29, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months4n, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.add(months4n),
1443, 8, "M08", 29, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months4n, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDate(
date14441230.add(months3n),
1444, 9, "M09", 29, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.add(months3n, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.add(months1n),
1442, 10, "M10", 29, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months1n, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14441230.add(months1n),
1444, 11, "M11", 29, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.add(months1n, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.add(months1n),
1442, 12, "M12", 29, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14430130.add(months1n, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -11,30 +11,282 @@ features: [Temporal, Intl.Era-monthcode]
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
const years1 = new Temporal.Duration(/* years = */ -1);
const years1n = new Temporal.Duration(1);
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.PlainDate.from({ year: 1443, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1443.subtract(years1n),
1442, Number(monthCode.slice(1)), monthCode, 29, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.subtract(years1n, options);
}, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.PlainDate.from({ year: 1442, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1442.subtract(years1),
1443, Number(monthCode.slice(1)), monthCode, 29, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.subtract(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.PlainDate.from({ year: 1443, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1443.subtract(years1),
1444, Number(monthCode.slice(1)), monthCode, 29, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.subtract(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.PlainDate.from({ year: 1444, monthCode: "M10", day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1444.subtract(years1n),
1443, 10, "M10", 29, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.subtract(years1n, options);
}, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const months1 = new Temporal.Duration(0, /* months = */ -1);
const months3 = new Temporal.Duration(0, -3);
const months5 = new Temporal.Duration(0, -5);
const months7 = new Temporal.Duration(0, -7);
const months8 = new Temporal.Duration(0, -8);
const months9 = new Temporal.Duration(0, -9);
const months10 = new Temporal.Duration(0, -10);
const months1n = new Temporal.Duration(0, 1);
const months3n = new Temporal.Duration(0, 3);
const months4n = new Temporal.Duration(0, 4);
const months6n = new Temporal.Duration(0, 6);
const months8n = new Temporal.Duration(0, 8);
const months10n = new Temporal.Duration(0, 10);
const date1 = Temporal.PlainDate.from({ year: 1447, monthCode: "M01", day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1.subtract(months1),
1447, 2, "M02", 29, "Day is constrained when adding months to a 30-day month and landing in a 29-day month",
"ah", 1447
);
const date14420230 = Temporal.PlainDate.from({ year: 1442, monthCode: "M02", day: 30, calendar }, options);
const date14430130 = Temporal.PlainDate.from({ year: 1443, monthCode: "M01", day: 30, calendar }, options);
const date14440230 = Temporal.PlainDate.from({ year: 1444, monthCode: "M02", day: 30, calendar} , options);
const date14421130 = Temporal.PlainDate.from({ year: 1442, monthCode: "M11", day: 30, calendar }, options);
const date14431230 = Temporal.PlainDate.from({ year: 1443, monthCode: "M12", day: 30, calendar }, options);
const date14441230 = Temporal.PlainDate.from({ year: 1444, monthCode: "M12", day: 30, calendar} , options);
assert.throws(RangeError, function () {
date1.subtract(months1, options);
}, "Adding months to a 30-day month and landing in a 29-day month rejects");
// Forwards
TemporalHelpers.assertPlainDate(
date1.subtract(months1n),
1446, 12, "M12", 29, "Day is constrained when subtracting months from a 30-day month and landing in a 29-day month",
"ah", 1446
);
date14431230.subtract(months1),
1444, 1, "M01", 29, "29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date1.subtract(months1n, options);
}, "Subtracting months from a 30-day month and landing in a 29-day month rejects");
date14431230.subtract(months4n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.subtract(months1),
1443, 2, "M02", 29, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months1, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.subtract(months1),
1442, 3, "M03", 29, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months1, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.subtract(months3),
1443, 4, "M04", 29, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months3, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.subtract(months3),
1442, 5, "M05", 29, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months3, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.subtract(months5),
1443, 6, "M06", 29, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months5, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.subtract(months5),
1442, 7, "M07", 29, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months5, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.subtract(months7),
1443, 8, "M08", 29, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months7, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDate(
date14440230.subtract(months7),
1444, 9, "M09", 29, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.subtract(months7, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.subtract(months8),
1442, 10, "M10", 29, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months8, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14440230.subtract(months9),
1444, 11, "M11", 29, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.subtract(months9, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.subtract(months10),
1442, 12, "M12", 29, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months10, options);
}, "29-day Dhu al-Hijjah rejects with 30");
// Backwards
TemporalHelpers.assertPlainDate(
date14421130.subtract(months10n),
1442, 1, "M01", 29, "29-day Muharram constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months10n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.subtract(months10n),
1443, 2, "M02", 29, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months10n, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.subtract(months8n),
1442, 3, "M03", 29, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months8n, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.subtract(months8n),
1443, 4, "M04", 29, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months8n, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.subtract(months6n),
1442, 5, "M05", 29, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months6n, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.subtract(months6n),
1443, 6, "M06", 29, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months6n, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.subtract(months4n),
1442, 7, "M07", 29, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months4n, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDate(
date14431230.subtract(months4n),
1443, 8, "M08", 29, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months4n, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDate(
date14441230.subtract(months3n),
1444, 9, "M09", 29, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.subtract(months3n, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDate(
date14421130.subtract(months1n),
1442, 10, "M10", 29, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months1n, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14441230.subtract(months1n),
1444, 11, "M11", 29, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.subtract(months1n, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.subtract(months1n),
1442, 12, "M12", 29, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14430130.subtract(months1n, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -0,0 +1,174 @@
// 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.with
description: Constraining the day for 29/30-day months in islamic-umalqura calendar
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.PlainDate.from({ year: 1443, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1443.with({ year: 1442 }),
1442, Number(monthCode.slice(1)), monthCode, 29, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.with({ year: 1442 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.PlainDate.from({ year: 1442, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1442.with({ year: 1443 }),
1443, Number(monthCode.slice(1)), monthCode, 29, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.with({ year: 1443 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.PlainDate.from({ year: 1443, monthCode, day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1443.with({ year: 1444 }),
1444, Number(monthCode.slice(1)), monthCode, 29, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.with({ year: 1444 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.PlainDate.from({ year: 1444, monthCode: "M10", day: 30, calendar }, options);
TemporalHelpers.assertPlainDate(
date1444.with({ year: 1443 }),
1443, 10, "M10", 29, `Changing the year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.with({ year: 1443 }, options);
}, `Changing the year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const date14420230 = Temporal.PlainDate.from({ year: 1442, monthCode: "M02", day: 30, calendar }, options);
const date14430130 = Temporal.PlainDate.from({ year: 1443, monthCode: "M01", day: 30, calendar }, options);
const date14441230 = Temporal.PlainDate.from({ year: 1444, monthCode: "M12", day: 30, calendar} , options);
// Forwards
TemporalHelpers.assertPlainDate(
date14441230.with({ monthCode: "M01" }),
1444, 1, "M01", 29, "29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M01" }, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.with({ monthCode: "M02" }),
1443, 2, "M02", 29, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M02" }, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.with({ monthCode: "M03" }),
1442, 3, "M03", 29, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M03" }, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.with({ monthCode: "M04" }),
1443, 4, "M04", 29, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M04" }, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.with({ monthCode: "M05" }),
1442, 5, "M05", 29, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M05" }, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.with({ monthCode: "M06" }),
1443, 6, "M06", 29, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M06" }, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.with({ monthCode: "M07" }),
1442, 7, "M07", 29, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M07" }, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDate(
date14430130.with({ monthCode: "M08" }),
1443, 8, "M08", 29, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M08" }, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDate(
date14441230.with({ monthCode: "M09" }),
1444, 9, "M09", 29, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M09" }, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.with({ monthCode: "M10" }),
1442, 10, "M10", 29, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M10" }, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDate(
date14441230.with({ monthCode: "M11" }),
1444, 11, "M11", 29, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M11" }, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDate(
date14420230.with({ monthCode: "M12" }),
1442, 12, "M12", 29, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M12" }, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -11,30 +11,282 @@ features: [Temporal, Intl.Era-monthcode]
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
const years1 = new Temporal.Duration(/* years = */ 1);
const years1n = new Temporal.Duration(-1);
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.PlainDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.add(years1n),
1442, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.add(years1n, options);
}, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.PlainDateTime.from({ year: 1442, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1442.add(years1),
1443, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.add(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.PlainDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.add(years1),
1444, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.add(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M10", day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1444.add(years1n),
1443, 10, "M10", 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.add(years1n, options);
}, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const months1 = new Temporal.Duration(0, /* months = */ 1);
const months3 = new Temporal.Duration(0, 3);
const months5 = new Temporal.Duration(0, 5);
const months7 = new Temporal.Duration(0, 7);
const months8 = new Temporal.Duration(0, 8);
const months9 = new Temporal.Duration(0, 9);
const months10 = new Temporal.Duration(0, 10);
const months1n = new Temporal.Duration(0, -1);
const months3n = new Temporal.Duration(0, -3);
const months4n = new Temporal.Duration(0, -4);
const months6n = new Temporal.Duration(0, -6);
const months8n = new Temporal.Duration(0, -8);
const months10n = new Temporal.Duration(0, -10);
const date1 = Temporal.PlainDateTime.from({ year: 1447, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1.add(months1),
1447, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when adding months to a 30-day month and landing in a 29-day month",
"ah", 1447
);
const date14420230 = Temporal.PlainDateTime.from({ year: 1442, monthCode: "M02", day: 30, hour: 12, minute: 34, calendar }, options);
const date14430130 = Temporal.PlainDateTime.from({ year: 1443, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }, options);
const date14440230 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M02", day: 30, hour: 12, minute: 34, calendar} , options);
const date14421130 = Temporal.PlainDateTime.from({ year: 1442, monthCode: "M11", day: 30, hour: 12, minute: 34, calendar }, options);
const date14431230 = Temporal.PlainDateTime.from({ year: 1443, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }, options);
const date14441230 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar} , options);
assert.throws(RangeError, function () {
date1.add(months1, options);
}, "Adding months to a 30-day month and landing in a 29-day month rejects");
// Forwards
TemporalHelpers.assertPlainDateTime(
date1.add(months1n),
1446, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when subtracting months from a 30-day month and landing in a 29-day month",
"ah", 1446
);
date14431230.add(months1),
1444, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date1.add(months1n, options);
}, "Subtracting months from a 30-day month and landing in a 29-day month rejects");
date14431230.add(months4n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months1),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months1, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months1),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months1, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months3),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months3, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months3),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months3, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months5),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months5, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months5),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months5, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months7),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months7, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.add(months7),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.add(months7, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months8),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months8, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.add(months9),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.add(months9, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months10),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months10, options);
}, "29-day Dhu al-Hijjah rejects with 30");
// Backwards
TemporalHelpers.assertPlainDateTime(
date14421130.add(months10n),
1442, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months10n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months10n),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months10n, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months8n),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months8n, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months8n),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months8n, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months6n),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months6n, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months6n),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months6n, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months4n),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months4n, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months4n),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months4n, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.add(months3n),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.add(months3n, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months1n),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months1n, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.add(months1n),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.add(months1n, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months1n),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14430130.add(months1n, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -11,30 +11,282 @@ features: [Temporal, Intl.Era-monthcode]
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
const years1 = new Temporal.Duration(/* years = */ -1);
const years1n = new Temporal.Duration(1);
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.PlainDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.subtract(years1n),
1442, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.subtract(years1n, options);
}, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.PlainDateTime.from({ year: 1442, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1442.subtract(years1),
1443, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.subtract(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.PlainDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.subtract(years1),
1444, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.subtract(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M10", day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1444.subtract(years1n),
1443, 10, "M10", 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.subtract(years1n, options);
}, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const months1 = new Temporal.Duration(0, /* months = */ -1);
const months3 = new Temporal.Duration(0, -3);
const months5 = new Temporal.Duration(0, -5);
const months7 = new Temporal.Duration(0, -7);
const months8 = new Temporal.Duration(0, -8);
const months9 = new Temporal.Duration(0, -9);
const months10 = new Temporal.Duration(0, -10);
const months1n = new Temporal.Duration(0, 1);
const months3n = new Temporal.Duration(0, 3);
const months4n = new Temporal.Duration(0, 4);
const months6n = new Temporal.Duration(0, 6);
const months8n = new Temporal.Duration(0, 8);
const months10n = new Temporal.Duration(0, 10);
const date1 = Temporal.PlainDateTime.from({ year: 1447, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1.subtract(months1),
1447, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when adding months to a 30-day month and landing in a 29-day month",
"ah", 1447
);
const date14420230 = Temporal.PlainDateTime.from({ year: 1442, monthCode: "M02", day: 30, hour: 12, minute: 34, calendar }, options);
const date14430130 = Temporal.PlainDateTime.from({ year: 1443, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }, options);
const date14440230 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M02", day: 30, hour: 12, minute: 34, calendar} , options);
const date14421130 = Temporal.PlainDateTime.from({ year: 1442, monthCode: "M11", day: 30, hour: 12, minute: 34, calendar }, options);
const date14431230 = Temporal.PlainDateTime.from({ year: 1443, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar }, options);
const date14441230 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar} , options);
assert.throws(RangeError, function () {
date1.subtract(months1, options);
}, "Adding months to a 30-day month and landing in a 29-day month rejects");
// Forwards
TemporalHelpers.assertPlainDateTime(
date1.subtract(months1n),
1446, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when subtracting months from a 30-day month and landing in a 29-day month",
"ah", 1446
);
date14431230.subtract(months1),
1444, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date1.subtract(months1n, options);
}, "Subtracting months from a 30-day month and landing in a 29-day month rejects");
date14431230.subtract(months4n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months1),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months1, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months1),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months1, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months3),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months3, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months3),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months3, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months5),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months5, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months5),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months5, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months7),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months7, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.subtract(months7),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.subtract(months7, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months8),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months8, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.subtract(months9),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.subtract(months9, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months10),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months10, options);
}, "29-day Dhu al-Hijjah rejects with 30");
// Backwards
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months10n),
1442, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months10n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months10n),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months10n, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months8n),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months8n, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months8n),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months8n, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months6n),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months6n, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months6n),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months6n, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months4n),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months4n, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months4n),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months4n, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.subtract(months3n),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.subtract(months3n, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months1n),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months1n, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.subtract(months1n),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.subtract(months1n, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months1n),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14430130.subtract(months1n, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -0,0 +1,174 @@
// 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.with
description: Constraining the day for 29/30-day months in islamic-umalqura calendar
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.PlainDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.with({ year: 1442 }),
1442, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0,`Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.with({ year: 1442 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.PlainDateTime.from({ year: 1442, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1442.with({ year: 1443 }),
1443, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0,`Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.with({ year: 1443 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.PlainDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.with({ year: 1444 }),
1444, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0,`Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.with({ year: 1444 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M10", day: 30, hour: 12, minute: 34, calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1444.with({ year: 1443 }),
1443, 10, "M10", 29, 12, 34, 0, 0, 0, 0,`Changing the year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.with({ year: 1443 }, options);
}, `Changing the year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const date14420230 = Temporal.PlainDateTime.from({ year: 1442, monthCode: "M02", day: 30, hour: 12, minute: 34, calendar }, options);
const date14430130 = Temporal.PlainDateTime.from({ year: 1443, monthCode: "M01", day: 30, hour: 12, minute: 34, calendar }, options);
const date14441230 = Temporal.PlainDateTime.from({ year: 1444, monthCode: "M12", day: 30, hour: 12, minute: 34, calendar} , options);
// Forwards
TemporalHelpers.assertPlainDateTime(
date14441230.with({ monthCode: "M01" }),
1444, 1, "M01", 29, 12, 34, 0, 0, 0, 0,"29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M01" }, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M02" }),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0,"29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M02" }, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M03" }),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0,"29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M03" }, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M04" }),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0,"29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M04" }, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M05" }),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0,"29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M05" }, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M06" }),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0,"29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M06" }, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M07" }),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0,"29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M07" }, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M08" }),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0,"29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M08" }, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.with({ monthCode: "M09" }),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0,"29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M09" }, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M10" }),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0,"29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M10" }, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.with({ monthCode: "M11" }),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0,"29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M11" }, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M12" }),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0,"29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M12" }, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -11,30 +11,282 @@ features: [Temporal, Intl.Era-monthcode]
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
const years1 = new Temporal.Duration(/* years = */ 1);
const years1n = new Temporal.Duration(-1);
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.ZonedDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.add(years1n).toPlainDateTime(),
1442, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.add(years1n, options);
}, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.ZonedDateTime.from({ year: 1442, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1442.add(years1).toPlainDateTime(),
1443, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.add(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.ZonedDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.add(years1).toPlainDateTime(),
1444, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.add(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M10", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1444.add(years1n).toPlainDateTime(),
1443, 10, "M10", 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.add(years1n, options);
}, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const months1 = new Temporal.Duration(0, /* months = */ 1);
const months3 = new Temporal.Duration(0, 3);
const months5 = new Temporal.Duration(0, 5);
const months7 = new Temporal.Duration(0, 7);
const months8 = new Temporal.Duration(0, 8);
const months9 = new Temporal.Duration(0, 9);
const months10 = new Temporal.Duration(0, 10);
const months1n = new Temporal.Duration(0, -1);
const months3n = new Temporal.Duration(0, -3);
const months4n = new Temporal.Duration(0, -4);
const months6n = new Temporal.Duration(0, -6);
const months8n = new Temporal.Duration(0, -8);
const months10n = new Temporal.Duration(0, -10);
const date1 = Temporal.ZonedDateTime.from({ year: 1447, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1.add(months1).toPlainDateTime(),
1447, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when adding months to a 30-day month and landing in a 29-day month",
"ah", 1447
);
const date14420230 = Temporal.ZonedDateTime.from({ year: 1442, monthCode: "M02", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14430130 = Temporal.ZonedDateTime.from({ year: 1443, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14440230 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M02", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar} , options);
const date14421130 = Temporal.ZonedDateTime.from({ year: 1442, monthCode: "M11", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14431230 = Temporal.ZonedDateTime.from({ year: 1443, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14441230 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar} , options);
assert.throws(RangeError, function () {
date1.add(months1, options);
}, "Adding months to a 30-day month and landing in a 29-day month rejects");
// Forwards
TemporalHelpers.assertPlainDateTime(
date1.add(months1n).toPlainDateTime(),
1446, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when subtracting months from a 30-day month and landing in a 29-day month",
"ah", 1446
);
date14431230.add(months1).toPlainDateTime(),
1444, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date1.add(months1n, options);
}, "Subtracting months from a 30-day month and landing in a 29-day month rejects");
date14431230.add(months4n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months1).toPlainDateTime(),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months1, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months1).toPlainDateTime(),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months1, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months3).toPlainDateTime(),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months3, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months3).toPlainDateTime(),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months3, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months5).toPlainDateTime(),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months5, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months5).toPlainDateTime(),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months5, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months7).toPlainDateTime(),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.add(months7, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.add(months7).toPlainDateTime(),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.add(months7, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months8).toPlainDateTime(),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months8, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.add(months9).toPlainDateTime(),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.add(months9, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.add(months10).toPlainDateTime(),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.add(months10, options);
}, "29-day Dhu al-Hijjah rejects with 30");
// Backwards
TemporalHelpers.assertPlainDateTime(
date14421130.add(months10n).toPlainDateTime(),
1442, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months10n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months10n).toPlainDateTime(),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months10n, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months8n).toPlainDateTime(),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months8n, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months8n).toPlainDateTime(),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months8n, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months6n).toPlainDateTime(),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months6n, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months6n).toPlainDateTime(),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months6n, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months4n).toPlainDateTime(),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months4n, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.add(months4n).toPlainDateTime(),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.add(months4n, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.add(months3n).toPlainDateTime(),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.add(months3n, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.add(months1n).toPlainDateTime(),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.add(months1n, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.add(months1n).toPlainDateTime(),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.add(months1n, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.add(months1n).toPlainDateTime(),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14430130.add(months1n, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -11,30 +11,282 @@ features: [Temporal, Intl.Era-monthcode]
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
const years1 = new Temporal.Duration(/* years = */ -1);
const years1n = new Temporal.Duration(1);
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.ZonedDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.subtract(years1n).toPlainDateTime(),
1442, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.subtract(years1n, options);
}, `Subtracting 1 year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.ZonedDateTime.from({ year: 1442, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1442.subtract(years1).toPlainDateTime(),
1443, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.subtract(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.ZonedDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.subtract(years1).toPlainDateTime(),
1444, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.subtract(years1, options);
}, `Adding 1 year to ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M10", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1444.subtract(years1n).toPlainDateTime(),
1443, 10, "M10", 29, 12, 34, 0, 0, 0, 0, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.subtract(years1n, options);
}, `Subtracting 1 year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const months1 = new Temporal.Duration(0, /* months = */ -1);
const months3 = new Temporal.Duration(0, -3);
const months5 = new Temporal.Duration(0, -5);
const months7 = new Temporal.Duration(0, -7);
const months8 = new Temporal.Duration(0, -8);
const months9 = new Temporal.Duration(0, -9);
const months10 = new Temporal.Duration(0, -10);
const months1n = new Temporal.Duration(0, 1);
const months3n = new Temporal.Duration(0, 3);
const months4n = new Temporal.Duration(0, 4);
const months6n = new Temporal.Duration(0, 6);
const months8n = new Temporal.Duration(0, 8);
const months10n = new Temporal.Duration(0, 10);
const date1 = Temporal.ZonedDateTime.from({ year: 1447, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1.subtract(months1).toPlainDateTime(),
1447, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when adding months to a 30-day month and landing in a 29-day month",
"ah", 1447
);
const date14420230 = Temporal.ZonedDateTime.from({ year: 1442, monthCode: "M02", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14430130 = Temporal.ZonedDateTime.from({ year: 1443, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14440230 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M02", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar} , options);
const date14421130 = Temporal.ZonedDateTime.from({ year: 1442, monthCode: "M11", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14431230 = Temporal.ZonedDateTime.from({ year: 1443, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14441230 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar} , options);
assert.throws(RangeError, function () {
date1.subtract(months1, options);
}, "Adding months to a 30-day month and landing in a 29-day month rejects");
// Forwards
TemporalHelpers.assertPlainDateTime(
date1.subtract(months1n).toPlainDateTime(),
1446, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "Day is constrained when subtracting months from a 30-day month and landing in a 29-day month",
"ah", 1446
);
date14431230.subtract(months1).toPlainDateTime(),
1444, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date1.subtract(months1n, options);
}, "Subtracting months from a 30-day month and landing in a 29-day month rejects");
date14431230.subtract(months4n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months1).toPlainDateTime(),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months1, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months1).toPlainDateTime(),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months1, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months3).toPlainDateTime(),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months3, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months3).toPlainDateTime(),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months3, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months5).toPlainDateTime(),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months5, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months5).toPlainDateTime(),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months5, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months7).toPlainDateTime(),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.subtract(months7, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.subtract(months7).toPlainDateTime(),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.subtract(months7, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months8).toPlainDateTime(),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months8, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14440230.subtract(months9).toPlainDateTime(),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14440230.subtract(months9, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.subtract(months10).toPlainDateTime(),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.subtract(months10, options);
}, "29-day Dhu al-Hijjah rejects with 30");
// Backwards
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months10n).toPlainDateTime(),
1442, 1, "M01", 29, 12, 34, 0, 0, 0, 0, "29-day Muharram constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months10n, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months10n).toPlainDateTime(),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0, "29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months10n, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months8n).toPlainDateTime(),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months8n, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months8n).toPlainDateTime(),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0, "29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months8n, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months6n).toPlainDateTime(),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months6n, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months6n).toPlainDateTime(),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0, "29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months6n, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months4n).toPlainDateTime(),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0, "29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months4n, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14431230.subtract(months4n).toPlainDateTime(),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0, "29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14431230.subtract(months4n, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.subtract(months3n).toPlainDateTime(),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0, "29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.subtract(months3n, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14421130.subtract(months1n).toPlainDateTime(),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0, "29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14421130.subtract(months1n, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.subtract(months1n).toPlainDateTime(),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.subtract(months1n, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.subtract(months1n).toPlainDateTime(),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0, "29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14430130.subtract(months1n, options);
}, "29-day Dhu al-Hijjah rejects with 30");

View File

@ -0,0 +1,174 @@
// 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.with
description: Constraining the day for 29/30-day months in islamic-umalqura calendar
includes: [temporalHelpers.js]
features: [Temporal, Intl.Era-monthcode]
---*/
const calendar = "islamic-umalqura";
const options = { overflow: "reject" };
// Observational month lengths in AH year:
// Y \ M 1 2 3 4 5 6 7 8 9 10 11 12
// 1442: 29 30 29 30 29 30 29 30 30 29 30 29
// 1443: 30 29 30 29 30 29 30 29 30 29 30 30
// 1444: 29 30 29 30 30 29 29 30 29 30 29 30
// Years
for (const monthCode of ["M01", "M03", "M05", "M07", "M12"]) {
const date1443 = Temporal.ZonedDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.with({ year: 1442 }).toPlainDateTime(),
1442, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0,`Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1442
);
assert.throws(RangeError, function () {
date1443.with({ year: 1442 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M02", "M04", "M06", "M08"]) {
const date1442 = Temporal.ZonedDateTime.from({ year: 1442, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1442.with({ year: 1443 }).toPlainDateTime(),
1443, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0,`Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1442.with({ year: 1443 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
for (const monthCode of ["M09", "M11"]) {
const date1443 = Temporal.ZonedDateTime.from({ year: 1443, monthCode, day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1443.with({ year: 1444 }).toPlainDateTime(),
1444, Number(monthCode.slice(1)), monthCode, 29, 12, 34, 0, 0, 0, 0,`Changing the year from ${monthCode}-30 into 29-day ${monthCode} constrains`,
"ah", 1444
);
assert.throws(RangeError, function () {
date1443.with({ year: 1444 }, options);
}, `Changing the year from ${monthCode}-30 into 29-day ${monthCode} rejects`);
}
const date1444 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M10", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
TemporalHelpers.assertPlainDateTime(
date1444.with({ year: 1443 }).toPlainDateTime(),
1443, 10, "M10", 29, 12, 34, 0, 0, 0, 0,`Changing the year from Shawwal 30 into 29-day Shawwal constrains`,
"ah", 1443
);
assert.throws(RangeError, function () {
date1444.with({ year: 1443 }, options);
}, `Changing the year from Shawwal 30 into 29-day Shawwal rejects`);
// Months
const date14420230 = Temporal.ZonedDateTime.from({ year: 1442, monthCode: "M02", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14430130 = Temporal.ZonedDateTime.from({ year: 1443, monthCode: "M01", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar }, options);
const date14441230 = Temporal.ZonedDateTime.from({ year: 1444, monthCode: "M12", day: 30, hour: 12, minute: 34, timeZone: "UTC", calendar} , options);
// Forwards
TemporalHelpers.assertPlainDateTime(
date14441230.with({ monthCode: "M01" }).toPlainDateTime(),
1444, 1, "M01", 29, 12, 34, 0, 0, 0, 0,"29-day Muharram constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M01" }, options);
}, "29-day Muharram rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M02" }).toPlainDateTime(),
1443, 2, "M02", 29, 12, 34, 0, 0, 0, 0,"29-day Safar constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M02" }, options);
}, "29-day Safar rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M03" }).toPlainDateTime(),
1442, 3, "M03", 29, 12, 34, 0, 0, 0, 0,"29-day Rabi' al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M03" }, options);
}, "29-day Rabi' al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M04" }).toPlainDateTime(),
1443, 4, "M04", 29, 12, 34, 0, 0, 0, 0,"29-day Rabi' al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M04" }, options);
}, "29-day Rabi' al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M05" }).toPlainDateTime(),
1442, 5, "M05", 29, 12, 34, 0, 0, 0, 0,"29-day Jumada al-Awwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M05" }, options);
}, "29-day Jumada al-Awwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M06" }).toPlainDateTime(),
1443, 6, "M06", 29, 12, 34, 0, 0, 0, 0,"29-day Jumada al-Thani constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M06" }, options);
}, "29-day Jumada al-Thani rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M07" }).toPlainDateTime(),
1442, 7, "M07", 29, 12, 34, 0, 0, 0, 0,"29-day Rajab constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M07" }, options);
}, "29-day Rajab rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14430130.with({ monthCode: "M08" }).toPlainDateTime(),
1443, 8, "M08", 29, 12, 34, 0, 0, 0, 0,"29-day Sha'ban constrains",
"ah", 1443);
assert.throws(RangeError, function () {
date14430130.with({ monthCode: "M08" }, options);
}, "29-day Sha'ban rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.with({ monthCode: "M09" }).toPlainDateTime(),
1444, 9, "M09", 29, 12, 34, 0, 0, 0, 0,"29-day Ramadan constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M09" }, options);
}, "29-day Ramadan rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M10" }).toPlainDateTime(),
1442, 10, "M10", 29, 12, 34, 0, 0, 0, 0,"29-day Shawwal constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M10" }, options);
}, "29-day Shawwal rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14441230.with({ monthCode: "M11" }).toPlainDateTime(),
1444, 11, "M11", 29, 12, 34, 0, 0, 0, 0,"29-day Dhu al-Qadah constrains",
"ah", 1444);
assert.throws(RangeError, function () {
date14441230.with({ monthCode: "M11" }, options);
}, "29-day Dhu al-Qadah rejects with 30");
TemporalHelpers.assertPlainDateTime(
date14420230.with({ monthCode: "M12" }).toPlainDateTime(),
1442, 12, "M12", 29, 12, 34, 0, 0, 0, 0,"29-day Dhu al-Hijjah constrains",
"ah", 1442);
assert.throws(RangeError, function () {
date14420230.with({ monthCode: "M12" }, options);
}, "29-day Dhu al-Hijjah rejects with 30");