moment: set does not update an invalid moment object

Description of the Issue and Steps to Reproduce: The issues stems from working with leap years and dates in “MMM DD” format. If I parse a leap year date (today, 2018) like “Feb 29” the moment object is invalidated. When I then try and change the year to a leap year, like 2020, the moment object is not updated.

> a = moment("Feb 29", "MMM DD")
> a.set('year', 2020)
> a.year()
< NaN
> a.toDate()
< Invalid Date

I am expecting a.year() to return “2020” and a.toDate() to return a date equal to “2020-02-29”.

The documentation does not mention that set() only works for valid objects.

Note that the above example only works if the current year is a non-leap year as moment assumes the current year if omitted in the parsed string.

Either code or docs need updating, imho.

Environment: Google Chrome Version 65.0.3325.181 (Official Build) (64-bit) Windows 10

Other information that may be helpful: If you are reporting an issue, please run the following code in the environment you are using and include the output:

console.log( (new Date()).toString())
Wed Apr 04 2018 14:24:03 GMT+0200 (W. Europe Daylight Time)
console.log((new Date()).toLocaleString())
4/4/2018, 2:24:03 PM
console.log( (new Date()).getTimezoneOffset())
-120
console.log( navigator.userAgent)
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
console.log(moment.version)
2.18.1

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 16 (7 by maintainers)

Most upvoted comments

@ichernev fully agree my use case is niche - I did end up doing exactly what you suggested and now I have a “proper” moment constructed, which does make a lot more sense. 😃

Still, I think the issue I mentioned previously is worth fixing:

moment('29 Feb', 'DD MMM') is flaky in a sense - the success of that function depends on the current year, so code that relies on it will literally start working in 2020 and then stop again in 2021.

Would be great if this was at least a warning.

So, it’s actually a Node.js app that’s processing data previously stored in the “DD MMM” format from a set of documents. I infer the date through other means, in a second pass, using a different storage where the metadata is stored that contains the year. Essentially, it’s a big mess and I’m using moment to correct the date format and have it include the year (among other things).

A niche use-case, I agree - but what bothers me is that I didn’t know this would happen until “Invalid date” started popping up in my output data.

I like the NaN analogy and I can see how the current “once invalid, always invalid” is a clear-cut approach, but perhaps “DD MMM” should just be an invalid format for the moment() function, as it includes no year?