Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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.plainmonthday.from
description: M13 month code is invalid for Buddhist calendar (12-month calendar)
features: [Temporal, Intl.Era-monthcode]
---*/

// The Buddhist calendar is a 12-month calendar and should not accept M13

const calendar = "buddhist";

assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 });
}, `M13 should not be a valid month code for ${calendar} calendar`);

// M13 should throw even with overflow: "constrain"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 }, { overflow: "constrain" });
}, `M13 should not be valid for ${calendar} calendar even with constrain overflow`);

// M13 should throw with overflow: "reject"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 }, { overflow: "reject" });
}, `M13 should not be valid for ${calendar} calendar with reject overflow`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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.plainmonthday.from
description: PlainMonthDay can be created for all month codes (M01-M12) in Buddhist calendar
features: [Temporal, Intl.Era-monthcode]
includes: [temporalHelpers.js]
---*/

// Test that all month codes M01-M12 are valid for the Buddhist calendar
// The Buddhist calendar follows the Gregorian calendar structure

const calendar = "buddhist";

for (const { monthCode, daysInMonth } of TemporalHelpers.ISOMonths) {
// Test creation with monthCode and day 1
const pmd = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 1 });
TemporalHelpers.assertPlainMonthDay(pmd, monthCode, 1, `monthCode ${monthCode} should be preserved`);

// Test with maximum day value for this month (minimum for PlainMonthDay)
const pmdMax = Temporal.PlainMonthDay.from({ calendar, monthCode, day: daysInMonth });
TemporalHelpers.assertPlainMonthDay(pmdMax, monthCode, daysInMonth, `${monthCode} with day ${daysInMonth} should be valid`);

// Test constrain overflow
const constrained = Temporal.PlainMonthDay.from(
{ calendar, monthCode, day: daysInMonth + 1 },
{ overflow: "constrain" }
);
TemporalHelpers.assertPlainMonthDay(constrained, monthCode, daysInMonth, `day ${daysInMonth + 1} should be constrained to ${daysInMonth} for ${monthCode}`);

// Test reject overflow
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode, day: daysInMonth + 1 }, { overflow: "reject" });
}, `${monthCode} with day ${daysInMonth + 1} should throw with reject overflow`);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.plainmonthday.from
description: M13 month code is invalid for Chinese calendar (12-month calendar with leap months)
features: [Temporal, Intl.Era-monthcode]
---*/

// The Chinese calendar is a 12-month lunisolar calendar with leap months (M01L-M12L)
// but does not have a thirteenth month (M13)

const calendar = "chinese";

assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 });
}, `M13 should not be a valid month code for ${calendar} calendar`);

// M13 should throw even with overflow: "constrain"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 }, { overflow: "constrain" });
}, `M13 should not be valid for ${calendar} calendar even with constrain overflow`);

// M13 should throw with overflow: "reject"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 }, { overflow: "reject" });
}, `M13 should not be valid for ${calendar} calendar with reject overflow`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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.plainmonthday.from
description: PlainMonthDay can be created for common leap month codes in Chinese calendar
features: [Temporal, Intl.Era-monthcode]
---*/

// Test common leap months in the Chinese calendar
// The Chinese calendar is a lunisolar calendar where leap months are inserted
// to keep the lunar year synchronized with the solar year.
// Common leap months (occurring more frequently in the astronomical cycle):
// M02L, M03L, M04L, M05L, M06L, M07L, M08L
//
// The distribution of leap months follows astronomical calculations.
//
// Note: M01L, M02L and M08L through M12L are temporarily omitted from this
// test because while any leap month can have 30 days, there isn't a year in the
// supported range where these months do, and it's not yet well-defined what
// reference ISO year should be used.
// See https://github.com/tc39/proposal-intl-era-monthcode/issues/60

const calendar = "chinese";

// Test leap months M03L-M07L with day 30
// These are well-established leap months that can have 30 days
const leapMonthsWith30Days = ["M03L", "M04L", "M05L", "M06L", "M07L"];

for (const monthCode of leapMonthsWith30Days) {
// Test creation with monthCode
const pmd = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 1 });
assert.sameValue(pmd.monthCode, monthCode, `leap monthCode ${monthCode} should be preserved`);
assert.sameValue(pmd.day, 1, `day should be 1 for ${monthCode}`);

// These leap months can have up to 30 days (minimum for PlainMonthDay)
const pmd30 = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 30 });
assert.sameValue(pmd30.monthCode, monthCode, `${monthCode} with day 30 should be valid`);
assert.sameValue(pmd30.day, 30, `day should be 30 for ${monthCode}`);

// Test constrain overflow - day 31 should be constrained to 30
const constrained = Temporal.PlainMonthDay.from(
{ calendar, monthCode, day: 31 },
{ overflow: "constrain" }
);
assert.sameValue(constrained.monthCode, monthCode, `${monthCode} should be preserved with constrain`);
assert.sameValue(constrained.day, 30, `day 31 should be constrained to 30 for ${monthCode}`);

// Test reject overflow - day 31 should throw
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode, day: 31 }, { overflow: "reject" });
}, `${monthCode} with day 31 should throw with reject overflow`);
}
43 changes: 43 additions & 0 deletions test/intl402/Temporal/PlainMonthDay/from/chinese-month-codes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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.plainmonthday.from
description: PlainMonthDay can be created for all regular month codes (M01-M12) in Chinese calendar
features: [Temporal, Intl.Era-monthcode]
---*/

// Test that all regular month codes M01-M12 are valid for the Chinese calendar
// The Chinese calendar is a lunisolar calendar, so months vary in length
// Leap months (M01L-M12L) are tested elsewhere

const calendar = "chinese";
const monthCodes = [
"M01", "M02", "M03", "M04", "M05", "M06",
"M07", "M08", "M09", "M10", "M11", "M12"
];

for (const monthCode of monthCodes) {
// Test creation with monthCode
const pmd = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 1 });
assert.sameValue(pmd.monthCode, monthCode, `monthCode ${monthCode} should be preserved`);
assert.sameValue(pmd.day, 1, "day should be 1");

// Test with day 30 (months can have 29 or 30 days)
const pmd30 = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 30 });
assert.sameValue(pmd30.monthCode, monthCode, `${monthCode} with day 30 should be valid`);
assert.sameValue(pmd30.day, 30, `day should be 30 for ${monthCode}`);

// Test constrain overflow - Chinese months vary from 29-30 days
const constrained = Temporal.PlainMonthDay.from(
{ calendar, monthCode, day: 31 },
{ overflow: "constrain" }
);
assert.sameValue(constrained.monthCode, monthCode, `${monthCode} should be preserved with constrain`);
assert.sameValue(constrained.day, 30, `day 31 should be constrained to 30 for ${monthCode}`);

// Test reject overflow for day 31
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode, day: 31 }, { overflow: "reject" });
}, `${monthCode} with day 31 should throw with reject overflow`);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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.plainmonthday.from
description: M14 month code is invalid for Coptic calendar (13-month calendar)
features: [Temporal, Intl.Era-monthcode]
---*/

// The Coptic calendar has 13 months (M01-M13) and should not accept M14

const calendar = "coptic";

assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M14", day: 1 });
}, `M14 should not be a valid month code for ${calendar} calendar`);

// M14 should throw even with overflow: "constrain"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M14", day: 1 }, { overflow: "constrain" });
}, `M14 should not be valid for ${calendar} calendar even with constrain overflow`);

// M14 should throw with overflow: "reject"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M14", day: 1 }, { overflow: "reject" });
}, `M14 should not be valid for ${calendar} calendar with reject overflow`);
65 changes: 65 additions & 0 deletions test/intl402/Temporal/PlainMonthDay/from/coptic-month-codes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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.plainmonthday.from
description: PlainMonthDay can be created for all month codes (M01-M13) in Coptic calendar
features: [Temporal, Intl.Era-monthcode]
---*/

// Test that all month codes M01-M13 are valid for the Coptic calendar
// The Coptic calendar has 12 months of 30 days each, plus a 13th month (Epagomenal days)
// of 5 or 6 days

const calendar = "coptic";

// M01-M12: Regular months with 30 days each
const regularMonthCodes = [
"M01", "M02", "M03", "M04", "M05", "M06",
"M07", "M08", "M09", "M10", "M11", "M12"
];

for (const monthCode of regularMonthCodes) {
// Test creation with monthCode
const pmd = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 1 });
assert.sameValue(pmd.monthCode, monthCode, `monthCode ${monthCode} should be preserved`);
assert.sameValue(pmd.day, 1, "day should be 1");

// Test with day 30 (all regular months have 30 days)
const pmd30 = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 30 });
assert.sameValue(pmd30.monthCode, monthCode, `${monthCode} with day 30 should be valid`);
assert.sameValue(pmd30.day, 30, `day should be 30 for ${monthCode}`);

// Test overflow: constrain to 30
const constrained = Temporal.PlainMonthDay.from(
{ calendar, monthCode, day: 31 },
{ overflow: "constrain" }
);
assert.sameValue(constrained.monthCode, monthCode, `${monthCode} should be preserved with constrain`);
assert.sameValue(constrained.day, 30, `day 31 should be constrained to 30 for ${monthCode}`);

// Test overflow: reject should throw for day 31
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode, day: 31 }, { overflow: "reject" });
}, `${monthCode} with day 31 should throw with reject overflow`);
}

// M13: Short month (Epagomenal days) with 5 or 6 days

// Test M13 with day 6 (maximum, valid in leap years)
const pmdM13Day6 = Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 6 });
assert.sameValue(pmdM13Day6.monthCode, "M13", "M13 should be valid with day 6");
assert.sameValue(pmdM13Day6.day, 6, "day should be 6 for M13");

// Test M13 overflow: constrain to maximum
const constrained = Temporal.PlainMonthDay.from(
{ calendar, monthCode: "M13", day: 7 },
{ overflow: "constrain" }
);
assert.sameValue(constrained.monthCode, "M13", "M13 should be preserved with constrain");
assert.sameValue(constrained.day, 6, "day 7 should be constrained to 6 for M13");

// Test M13 overflow: reject should throw for day 7
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 7 }, { overflow: "reject" });
}, "M13 with day 7 should throw with reject overflow");
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.plainmonthday.from
description: M13 month code is invalid for Dangi calendar (12-month calendar with leap months)
features: [Temporal, Intl.Era-monthcode]
---*/

// The Dangi calendar is a 12-month lunisolar calendar with leap months (M01L-M12L)
// but does not have a thirteenth month (M13)

const calendar = "dangi";

assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 });
}, `M13 should not be a valid month code for ${calendar} calendar`);

// M13 should throw even with overflow: "constrain"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 }, { overflow: "constrain" });
}, `M13 should not be valid for ${calendar} calendar even with constrain overflow`);

// M13 should throw with overflow: "reject"
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode: "M13", day: 1 }, { overflow: "reject" });
}, `M13 should not be valid for ${calendar} calendar with reject overflow`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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.plainmonthday.from
description: PlainMonthDay can be created for common leap month codes in Dangi calendar
features: [Temporal, Intl.Era-monthcode]
---*/

// Test common leap months in the Dangi calendar
// Dangi is a lunisolar calendar where leap months follow the same distribution as Chinese
// Common leap months (occurring more frequently in the astronomical cycle):
// M02L, M03L, M04L, M05L, M06L, M07L, M08L
//
// Like the Chinese calendar, the Dangi calendar inserts leap months to keep the
// lunar year synchronized with the solar year. The distribution of leap months
// follows astronomical calculations.
//
// Note: M01L, M02L and M08L through M12L are temporarily omitted from this
// test because while any leap month can have 30 days, there isn't a year in the
// supported range where these months do, and it's not yet well-defined what
// reference ISO year should be used.
// See https://github.com/tc39/proposal-intl-era-monthcode/issues/60

const calendar = "dangi";

// Test leap months M03L-M07L with day 30
// These are well-established leap months that can have 30 days
const leapMonthsWith30Days = ["M03L", "M04L", "M05L", "M06L", "M07L"];

for (const monthCode of leapMonthsWith30Days) {
// Test creation with monthCode
const pmd = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 1 });
assert.sameValue(pmd.monthCode, monthCode, `leap monthCode ${monthCode} should be preserved`);
assert.sameValue(pmd.day, 1, `day should be 1 for ${monthCode}`);

// These leap months can have up to 30 days (minimum for PlainMonthDay)
const pmd30 = Temporal.PlainMonthDay.from({ calendar, monthCode, day: 30 });
assert.sameValue(pmd30.monthCode, monthCode, `${monthCode} with day 30 should be valid`);
assert.sameValue(pmd30.day, 30, `day should be 30 for ${monthCode}`);

// Test constrain overflow - day 31 should be constrained to 30
const constrained = Temporal.PlainMonthDay.from(
{ calendar, monthCode, day: 31 },
{ overflow: "constrain" }
);
assert.sameValue(constrained.monthCode, monthCode, `${monthCode} should be preserved with constrain`);
assert.sameValue(constrained.day, 30, `day 31 should be constrained to 30 for ${monthCode}`);

// Test reject overflow - day 31 should throw
assert.throws(RangeError, () => {
Temporal.PlainMonthDay.from({ calendar, monthCode, day: 31 }, { overflow: "reject" });
}, `${monthCode} with day 31 should throw with reject overflow`);
}
Loading