diff --git a/polyfill/lib/calendar.mjs b/polyfill/lib/calendar.mjs
index a494a7bf94..cbc93ee33e 100644
--- a/polyfill/lib/calendar.mjs
+++ b/polyfill/lib/calendar.mjs
@@ -324,9 +324,6 @@ impl['iso8601'] = {
monthDayFromFields(fields, options, calendarSlotValue) {
fields = ES.PrepareTemporalFields(fields, ['day', 'month', 'monthCode', 'year'], ['day']);
const overflow = ES.ToTemporalOverflow(options);
- if (fields.month !== undefined && fields.year === undefined && fields.monthCode === undefined) {
- throw new TypeError('either year or monthCode required with month');
- }
const referenceISOYear = 1972;
fields = resolveNonLunisolarMonth(fields);
let { month, day, year } = fields;
@@ -701,7 +698,7 @@ const nonIsoHelperBase = {
}
if (this.hasEra) {
if ((calendarDate['era'] === undefined) !== (calendarDate['eraYear'] === undefined)) {
- throw new RangeError("properties 'era' and 'eraYear' must be provided together");
+ throw new TypeError("properties 'era' and 'eraYear' must be provided together");
}
}
},
diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs
index 9fa10ac025..03fa2336b6 100644
--- a/polyfill/lib/ecmascript.mjs
+++ b/polyfill/lib/ecmascript.mjs
@@ -1345,24 +1345,16 @@ export function ToTemporalMonthDay(item, options) {
if (options !== undefined) options = SnapshotOwnProperties(GetOptionsObject(options), null);
if (Type(item) === 'Object') {
if (IsTemporalMonthDay(item)) return item;
- let calendar, calendarAbsent;
+ let calendar;
if (HasSlot(item, CALENDAR)) {
calendar = GetSlot(item, CALENDAR);
- calendarAbsent = false;
} else {
calendar = item.calendar;
- calendarAbsent = calendar === undefined;
if (calendar === undefined) calendar = 'iso8601';
calendar = ToTemporalCalendarSlotValue(calendar);
}
const fieldNames = CalendarFields(calendar, ['day', 'month', 'monthCode', 'year']);
const fields = PrepareTemporalFields(item, fieldNames, []);
- // Callers who omit the calendar are not writing calendar-independent
- // code. In that case, `monthCode`/`year` can be omitted; `month` and
- // `day` are sufficient. Add a `year` to satisfy calendar validation.
- if (calendarAbsent && fields.month !== undefined && fields.monthCode === undefined && fields.year === undefined) {
- fields.year = 1972;
- }
return CalendarMonthDayFromFields(calendar, fields, options);
}
@@ -1373,6 +1365,9 @@ export function ToTemporalMonthDay(item, options) {
ToTemporalOverflow(options); // validate and ignore
if (referenceISOYear === undefined) {
+ if (calendar !== 'iso8601') {
+ throw new Error(`assertion failed: missing year with non-"iso8601" calendar identifier ${calendar}`);
+ }
RejectISODate(1972, month, day);
return CreateTemporalMonthDay(month, day, calendar);
}
diff --git a/polyfill/test262 b/polyfill/test262
index dceb204259..892a5dccd2 160000
--- a/polyfill/test262
+++ b/polyfill/test262
@@ -1 +1 @@
-Subproject commit dceb204259abc800b7a6ec7bccf07f9a7c69297d
+Subproject commit 892a5dccd2a59a63f3a363db07f53bf896912699
diff --git a/spec/calendar.html b/spec/calendar.html
index 8b153b8f7d..23653f10af 100644
--- a/spec/calendar.html
+++ b/spec/calendar.html
@@ -917,7 +917,7 @@
ISOMonthDayFromFields ( _fields_, _overflow_ )
1. Let _day_ be ! Get(_fields_, *"day"*).
1. Assert: _month_ and _day_ are Numbers.
1. Let _year_ be ! Get(_fields_, *"year"*).
- 1. Let _referenceISOYear_ be 1972 (the first leap year after the epoch).
+ 1. Let _referenceISOYear_ be 1972 (the first ISO 8601 leap year after the epoch).
1. If _year_ is *undefined*, then
1. Let _result_ be ? RegulateISODate(_referenceISOYear_, ℝ(_month_), ℝ(_day_), _overflow_).
1. Else,
diff --git a/spec/intl.html b/spec/intl.html
index 1ac51aef19..2b5ed4a7af 100644
--- a/spec/intl.html
+++ b/spec/intl.html
@@ -1855,6 +1855,7 @@
- If _type_ is ~date~ or ~month-day~ and *"day"* in the calendar has an interpretation analogous to ISO 8601 and its corresponding value is *undefined*.
- If *"month"* and *"monthCode"* in the calendar have interpretations analogous to ISO 8601 and either the corresponding values for both are *undefined* or neither value is *undefined* but they do not identify the same month.
+ - If _type_ is ~month-day~ and the value for *"monthCode"* is *undefined* and a year cannot be determined from _fields_.
- If _type_ is ~date~ or ~year-month~ and the calendar supports the usual partitioning of years into eras with their own year counting as represented by *"year"*, *"era"*, and *"eraYear"* (as in the Gregorian or traditional Japanese calendars) and any of the following cases apply:
- The value for each of *"year"* and *"era"* and *"eraYear"* is *undefined*.
- The value for *"era"* is *undefined* but the value for *"eraYear"* is not.
@@ -1862,6 +1863,9 @@
- None of the three values are *undefined* but the values for *"era"* and *"eraYear"* do not together identify the same year as the value for *"year"*.
+
+ When _type_ is ~month-day~ and *"month"* is provided without *"monthCode"*, it is recommended that all built-in calendars other than the ISO 8601 calendar require a disambiguating year (e.g., either *"year"* or *"era"* and *"eraYear"*), including those that always use exactly the same months as the ISO 8601 calendar (which receives special handling in this specification as a default calendar that is permanently stable for automated processing).
+
diff --git a/spec/plainmonthday.html b/spec/plainmonthday.html
index 44a2ecf6b4..57d9aa874a 100644
--- a/spec/plainmonthday.html
+++ b/spec/plainmonthday.html
@@ -32,14 +32,13 @@ Temporal.PlainMonthDay ( _isoMonth_, _isoDay_ [ , _calendarLike_ [ , _refere
1. If NewTarget is *undefined*, then
1. Throw a *TypeError* exception.
1. If _referenceISOYear_ is *undefined*, then
- 1. Set _referenceISOYear_ to *1972*𝔽.
+ 1. Set _referenceISOYear_ to *1972*𝔽 (the first ISO 8601 leap year after the epoch).
1. Let _m_ be ? ToIntegerWithTruncation(_isoMonth_).
1. Let _d_ be ? ToIntegerWithTruncation(_isoDay_).
1. Let _calendar_ be ? ToTemporalCalendarSlotValue(_calendarLike_, *"iso8601"*).
- 1. Let _ref_ be ? ToIntegerWithTruncation(_referenceISOYear_).
- 1. Return ? CreateTemporalMonthDay(_m_, _d_, _calendar_, _ref_, NewTarget).
+ 1. Let _y_ be ? ToIntegerWithTruncation(_referenceISOYear_).
+ 1. Return ? CreateTemporalMonthDay(_m_, _d_, _calendar_, _y_, NewTarget).
- 1972 is the first leap year after the epoch.
@@ -366,27 +365,16 @@
1. If _options_ is not present, set _options_ to *undefined*.
1. If _options_ is not *undefined*, set _options_ to ? SnapshotOwnProperties(! GetOptionsObject(_options_), *null*).
- 1. Let _referenceISOYear_ be 1972 (the first leap year after the epoch).
1. If Type(_item_) is Object, then
1. If _item_ has an [[InitializedTemporalMonthDay]] internal slot, then
1. Return _item_.
1. If _item_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
1. Let _calendar_ be _item_.[[Calendar]].
- 1. Let _calendarAbsent_ be *false*.
1. Else,
1. Let _calendarLike_ be ? Get(_item_, *"calendar"*).
- 1. If _calendarLike_ is *undefined*, then
- 1. Let _calendarAbsent_ be *true*.
- 1. Else,
- 1. Let _calendarAbsent_ be *false*.
1. Let _calendar_ be ? ToTemporalCalendarSlotValue(_calendarLike_, *"iso8601"*).
1. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »).
1. Let _fields_ be ? PrepareTemporalFields(_item_, _fieldNames_, «»).
- 1. Let _month_ be ! Get(_fields_, *"month"*).
- 1. Let _monthCode_ be ! Get(_fields_, *"monthCode"*).
- 1. Let _year_ be ! Get(_fields_, *"year"*).
- 1. If _calendarAbsent_ is *true*, and _month_ is not *undefined*, and _monthCode_ is *undefined* and _year_ is *undefined*, then
- 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"year"*, 𝔽(_referenceISOYear_)).
1. Return ? CalendarMonthDayFromFields(_calendar_, _fields_, _options_).
1. If _item_ is not a String, throw a *TypeError* exception.
1. Let _result_ be ? ParseTemporalMonthDayString(_item_).
@@ -396,6 +384,8 @@
1. Set _calendar_ to the ASCII-lowercase of _calendar_.
1. Perform ? ToTemporalOverflow(_options_).
1. If _result_.[[Year]] is *undefined*, then
+ 1. Assert: _calendar_ is *"iso8601"*.
+ 1. Let _referenceISOYear_ be 1972 (the first ISO 8601 leap year after the epoch).
1. Return ? CreateTemporalMonthDay(_result_.[[Month]], _result_.[[Day]], _calendar_, _referenceISOYear_).
1. Set _result_ to ? CreateTemporalMonthDay(_result_.[[Month]], _result_.[[Day]], _calendar_, _result_.[[Year]]).
1. NOTE: The following operation is called without _options_, in order for the calendar to store a canonical value in the [[ISOYear]] internal slot of the result.