diff --git a/polyfill/lib/calendar.mjs b/polyfill/lib/calendar.mjs index c5cfe9195..f8e639675 100644 --- a/polyfill/lib/calendar.mjs +++ b/polyfill/lib/calendar.mjs @@ -243,12 +243,12 @@ function resolveNonLunisolarMonth(calendarDate, overflow = undefined, monthsPerY monthCode = buildMonthCode(month); } else { const numberPart = monthCodeNumberPart(monthCode); - if (month !== undefined && month !== numberPart) { - throw new RangeError(`monthCode ${monthCode} and month ${month} must match if both are present`); - } if (monthCode !== buildMonthCode(numberPart)) { throw new RangeError(`Invalid month code: ${monthCode}`); } + if (month !== undefined && month !== numberPart) { + throw new RangeError(`monthCode ${monthCode} and month ${month} must match if both are present`); + } month = numberPart; if (month < 1 || month > monthsPerYear) throw new RangeError(`Invalid monthCode: ${monthCode}`); } @@ -858,12 +858,11 @@ const nonIsoHelperBase = { // Override if calendar uses eras hasEra: false, monthDayFromFields(fields, overflow, cache) { - let { monthCode, day } = fields; - if (monthCode === undefined) { - let { year, era, eraYear } = fields; - if (year === undefined && (era === undefined || eraYear === undefined)) { - throw new TypeError('when `monthCode` is omitted, `year` (or `era` and `eraYear`) and `month` are required'); - } + let { era, eraYear, year, month, monthCode, day } = fields; + if (month !== undefined && year === undefined && (!this.hasEra || era === undefined || eraYear === undefined)) { + throw new TypeError('when month is present, year (or era and eraYear) are required'); + } + if (monthCode === undefined || year !== undefined || (this.hasEra && eraYear !== undefined)) { // Apply overflow behaviour to year/month/day, to get correct monthCode/day ({ monthCode, day } = this.isoToCalendarDate(this.calendarToIsoDate(fields, overflow, cache), cache)); } @@ -1785,8 +1784,6 @@ const nonIsoGeneralImpl = { const largestMonth = this.helper.monthsInYear(fields, cache); resolveNonLunisolarMonth(fields, undefined, largestMonth); } - // For lunisolar calendars, either `monthCode` or `year` must be provided - // because `month` is ambiguous without a year or a code. const result = this.helper.monthDayFromFields(fields, overflow, cache); // result.year is a reference year where this month/day exists in this calendar cache.setObject(result); diff --git a/spec/calendar.html b/spec/calendar.html index 26bc8e7e7..d0802c1ec 100644 --- a/spec/calendar.html +++ b/spec/calendar.html @@ -1224,7 +1224,7 @@
- Like RegulateISODate, the operation throws a *RangeError* exception if _overflow_ is *"reject"* and the month and day described by _fields_ does not exist. + Like RegulateISODate, the operation throws a *RangeError* exception if _overflow_ is *"reject"* and the month and day described by _fields_ does not exist (or does not exist within the year described by _fields_ when there is such a year). For example, when _calendar_ is *"gregory"* and _overflow_ is *"reject"*, _fields_ values of { [[MonthCode]]: *"M01"*, [[Day]]: 32 } and { [[Year]]: 2001, [[Month]]: 2, [[Day]]: 29 } would both cause a *RangeError* to be thrown. In the latter case, even though February 29 is a date in leap years of the Gregorian calendar, 2001 was not a leap year and a month code cannot be determined from the nonexistent date 2001-02-29 with the specified month index.
@@ -1381,16 +1381,16 @@