PlainYearMonth objects with a Gregorian calendar do not work correctly when subtracting months in some cases
See original GitHub issueThe title is a mouthful, so just to break it down - subtraction of months does not work when:
- It is done on a PlainYearMonth
- The object has a calendar
- The calendar is “gregory”
- The month of the object 31 days. For example, December (12).
Here is a code example:
const date = new Temporal.PlainYearMonth(2021, 12, "gregory");
const result = date.subtract({ months: 4 });
console.log("date", date.toString(), result.toString());
The log result is
date: 2021-12-01[u-ca=gregory] 2021-12-01[u-ca=gregory]
The month stays the same if it’s December. I debugged it and it seems to be a problem of having a calendar attached - when subtraction happens, it sets the day to 31
(the last day of the month) and then it tries to subtract 30 days four times (for the four months being subtracted) but each iteration in the loop, it sets the date to subtract from as 2021-12-31
, so it ends in 2021-12-01
not shifting the month, then next iteration it subtracts from the last day of the month again: 2021-12-31
Weirdly, not all 31 day months work the same. And not all 30 day months work the same, either. Here is my test for trying to subtract 4 months from various times in 2021:
Date | Start date | End date | result |
---|---|---|---|
new Temporal.PlainYearMonth(2021, 1, "gregory") |
2021-01-01[u-ca=gregory] | 2020-12-01[u-ca=gregory] | ❌1 month shift. |
new Temporal.PlainYearMonth(2021, 2, "gregory") |
2021-02-01[u-ca=gregory] | 2020-10-01[u-ca=gregory] | ✔ correct 4 month shift. |
new Temporal.PlainYearMonth(2021, 3, "gregory") |
2021-03-01[u-ca=gregory] | 2021-03-01[u-ca=gregory] | ❌ no shift. |
new Temporal.PlainYearMonth(2021, 4, "gregory") |
2021-04-01[u-ca=gregory] | 2021-03-01[u-ca=gregory] | ❌ 1 month shift. |
new Temporal.PlainYearMonth(2021, 5, "gregory") |
2021-05-01[u-ca=gregory] | 2021-05-01[u-ca=gregory] | ❌ no shift. |
new Temporal.PlainYearMonth(2021, 6, "gregory") |
2021-06-01[u-ca=gregory] | 2021-03-01[u-ca=gregory] | ❌ 3 months shift. |
new Temporal.PlainYearMonth(2021, 7, "gregory") |
2021-07-01[u-ca=gregory] | 2021-07-01[u-ca=gregory] | ❌ no shift. |
new Temporal.PlainYearMonth(2021, 8, "gregory") |
2021-08-01[u-ca=gregory] | 2021-07-01[u-ca=gregory] | ❌ 1 month shift. |
new Temporal.PlainYearMonth(2021, 9, "gregory") |
2021-09-01[u-ca=gregory] | 2021-05-01[u-ca=gregory] | ✔ correct 4 month shift. |
new Temporal.PlainYearMonth(2021, 10, "gregory") |
2021-10-01[u-ca=gregory] | 2021-10-01[u-ca=gregory] | ❌ no shift. |
new Temporal.PlainYearMonth(2021, 11, "gregory") |
2021-11-01[u-ca=gregory] | 2021-07-01[u-ca=gregory] | ✔ correct 4 month shift. |
new Temporal.PlainYearMonth(2021, 12, "gregory") |
2021-12-01[u-ca=gregory] | 2021-12-01[u-ca=gregory] | ❌ no shift. |
It appears that the majority of the months do not work when subtracting and most likely because they fail on the previous month. January rolls over to December then fails to subtract three times.
Seems that having a day because of the Gregorian calendar is an issue. Using "iso8601"
as a calendar does not cause this behaviour. I have not tried other calendars.
The version of the @js-temporal/polyfill package is 0.2.0
You can find a runnable example in this CodeSandbox
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (5 by maintainers)
Updating to 0.3.0 has fixed the issue. Thanks!
BTW, we just released 0.3.0. Let us know if the problem still shows up in the latest release and we can re-open this issue.