Victor Lebkowski
Victor Lebkowski

Reputation: 67

Moment automatically corrects invalid dates when setting one

Im setting a date with moment library by catching, day month and year from inputs :

var userDate = moment().set({ 'year': oTextY.innerHTML, 'month': oTextMi.innerHTML - 1, 'day': oTextDi.innerHTML });

If in the input i specify feb 31 2005 it gives me March 16 2005

Anyone have any idea to prevent this weird behavior ? :)

Upvotes: 1

Views: 72

Answers (2)

Maggie Pint
Maggie Pint

Reputation: 2452

You have a couple things going on here. First of all, 'day' is the word for 'day of week', not 'date of month'. I think you are looking for 'date'. It is not intuitive.

Next, setters in moment overflow into the next unit. In 2005, February had 28 days, so when you attempt to set to February 31, the set operation is going to overflow into the next month by the number of extra days, and the resultant date will be 2005-03-03.

As such, your corrected code would be:

var userDate = moment().set({ 'year': oTextY.innerHTML, 
'month': oTextMi.innerHTML - 1, 'date': oTextDi.innerHTML });

And your expected output would be:

"2005-03-03T07:25:36-06:00"

Though the offset would of course be local to your computer, not mine.

It sounds as though you are trying to validate the date inputs, and then compare it to another date. That being the case, probably the easiest thing to do is to actually just parse your inputs as a string:

moment(oTextY.innerHTML + '-' + oTextMi.innerHTML + '-' + oTextDi.innerHTML,
'YYYY-MM-DD') 

You will notice that if you pass this the inputs you provided, you will get invalid date:

moment(2005 + '-' + 2+ '-' + 31,
'YYYY-MM-DD').isValid()
false

If you need to compare this moment to another moment, regardless of time, just use isSame() with day:

var a = moment(oTextY.innerHTML + '-' + oTextMi.innerHTML + '-' + oTextDi.innerHTML,
'YYYY-MM-DD') 
a.isSame(moment(), 'day') //api uses day here because inconsistency is what programmers do

As for why when you use day instead of date you get the 16th. This has to do with the way moment overflows day of week sets. This is somewhat complex, but is explained fairly well in the docs here: http://momentjs.com/docs/#/get-set/day/

If you want a more complete explanation, feel free to comment back and I'll go through it. I think mainly what you need to know is that you should use date.

Upvotes: 1

Qianyue
Qianyue

Reputation: 1777

The month starts by 0, you can just add 1 when you set your date:

var userDate = moment().set({ 'year': oTextY.innerHTML, 'month': oTextMi.innerHTML + 1, 'day': oTextDi.innerHTML });

Upvotes: 0

Related Questions