-
Notifications
You must be signed in to change notification settings - Fork 174
Description
PlainMonthDay.from() accepts an overflow: 'constrain' | 'reject' option. How should this option behave when the input is a leap day or a day in a leap month? In the ISO calendar this is easy because there's only one leap day and it's always at the end of the same month. So the ISO calendar can use a fixed reference year, which currently is 1972 which was the first leap year after UNIX epoch.
However, non-ISO calendars:
- Can have leap months (e.g. Hebrew, Chinese) which are not present every year
- Can have variable-length months, most commonly because month start and endpoints are determined by the position of the moon at a particular place and/or measured in a particular way (e.g. Islamic, Chinese)
This means that the ISO reference year cannot be a constant, and it makes it harder to know how overflow should behave.
My assumption is that the correct overflow behavior in any calendar is this:
'constrain'- try to find a year where this month/day exists. If one can be found, use it for computation ofreferenceISOYear. If one cannot be found:- If month is smaller than any month in any known year, then use the first month in years.
- If month is larger than any month in any known year, then use the last month in the longest known year
- If day is smaller than any valid day, then use the first day of the month
- If day is larger than any day of the month calculated above, then use the largest day of this month in any known year.
'reject'- try to find a year where this month/day exists. If one can be found, use it for computation ofreferenceISOYear. If one cannot be found, throw aRangeError.
In my non-ISO calendar PR, I'm implementing the logic above by starting from the current date and working backwards one calendar year at a time for up to 100 years to try to find a year where the month/day exists. AFAICT, all built-in calendars have cycle lengths less than 100 years so if a match is going to happen, it should happen within a century. (I'm actually optimizing a little by checking for definitely-invalid values like day: 0 or month: 14 before doing the up-to-100-year loop on maybe-valid month/day pairs, but that optimization shouldn't affect the spec above.)
If you disagree with this approach, LMK soon!
EDIT: How should the calendar react to an invalid leap-month monthCode, e.g. '4L' for any calendar other than Chinese/Dangi. Should it constrain down to the last day of monthCode: '4' per the constrain algorithm in the OP? Or throw a RangeError because that month code is never valid for that calendar?