question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

PlainYearMonth objects with a Gregorian calendar do not work correctly when subtracting months in some cases

See original GitHub issue

The 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:closed
  • Created 2 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
PurpleMagickcommented, Dec 11, 2021

Updating to 0.3.0 has fixed the issue. Thanks!

0reactions
justingrantcommented, Dec 11, 2021

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Temporal.PlainYearMonth - TC39
PlainYearMonth instances where the year and month and day are identical, ... If the calendar property is not present, it's assumed to be...
Read more >
proposal-temporal/plainyearmonth.md at main · tc39/proposal ...
PlainYearMonth object, a new object representing the same month is returned. ... If the calendar property is not present, it's assumed to be...
Read more >
Temporal js yearMonth.subtract return the same month
plainDate("gregory") works - it's the calendar messing up the calculations. It seems to make a PlainYearMonth date into one with a day always....
Read more >
Temporal: getting started with JavaScript's new date time API
Changing them produces new values, similarly to how strings work in JavaScript. There is support for time zones and non-Gregorian calendars.
Read more >
JavaScript Temporal API- A Fix for the Date API - Bits and Pieces
Changing the way Date API works will most likely break many ... this kind of mutable object will cause bugs when not handled...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found