159
votes

Following is the scenario:

I have a String date and a date format which is different. Ex.:
date: 2016-10-19
dateFormat: "DD-MM-YYYY".

I need to check if this date is a valid date.

I have tried following things

var d = moment("2016-10-19",dateFormat);

d.isValid() is returning false every time. Does not Moment.js parse the date in the given format?

Then I tried to format the date in DD-MM-YYYY first and then pass it to Moment.js:

var d = moment("2016-10-19").format(dateFormat);
var date = moment(d, dateFormat);

Now date.isValid() is giving me the desired result, but here the Moment.js date object is created twice. How can I avoid this? Is there a better solution?

FYI I am not allowed to change the dateFormat.

9
Are you not allowed to change the value of dateFormat? In that case, you will have to change the format of the input, since 2016-10-19 is YYYY-MM-DD, not DD-MM-YYYY. What are you allowed to change?Pochen
The input is coming from date picker. Can't change that too :(Ganesh
May I ask why you are not allowed to change the dateFormat variable? var d = moment("19-10-2016", "DD-MM-YYYY"); would solve your problems as far as I'm concernedPochen
really can't say. But that is not in my control to change that value.Ganesh

9 Answers

224
votes

Was able to find the solution. Since the date I am getting is in ISO format, only providing date to moment will validate it, no need to pass the dateFormat.

var date = moment("2016-10-19");

And then date.isValid() gives desired result.

142
votes

var date = moment('2016-10-19', 'DD-MM-YYYY', true);

You should add a third argument when invoking moment that enforces strict parsing. Here is the relevant portion of the moment documentation http://momentjs.com/docs/#/parsing/string-format/ It is near the end of the section.

19
votes

Here you go: Working Fidddle

$(function(){
  var dateFormat = 'DD-MM-YYYY';
  alert(moment(moment("2012-10-19").format(dateFormat),dateFormat,true).isValid());
});
18
votes

I use moment along with new Date to handle cases of undefined data values:

const date = moment(new Date("2016-10-19"));

because of: moment(undefined).isValid() == true

where as the better way: moment(new Date(undefined)).isValid() == false

18
votes

I just found a really messed up case.

moment('Decimal128', 'YYYY-MM-DD').isValid() // true
16
votes

How to check if a string is a valid date using Moment, when the date and date format are different

Sorry, but did any of the given solutions on this thread actually answer the question that was asked?

I have a String date and a date format which is different. Ex.: date: 2016-10-19 dateFormat: "DD-MM-YYYY". I need to check if this date is a valid date.

The following works for me...

const date = '2016-10-19';
const dateFormat = 'DD-MM-YYYY';
const toDateFormat = moment(new Date(date)).format(dateFormat);
moment(toDateFormat, dateFormat, true).isValid();

// Note: `new Date()` circumvents the warning that
// Moment throws (https://momentjs.com/guides/#/warnings/js-date/),
// but may not be optimal.

But honestly, don't understand why moment.isDate()(as documented) only accepts an object. Should also support a string in my opinion.

4
votes
console.log(` moment('2019-09-01', 'YYYY-MM-DD').isValid()?  ` +moment('2019-09-01', 'YYYY-MM-DD').isValid())
console.log(` moment('2019-22-01', 'YYYY-DD-MM').isValid()?  ` +moment('2019-22-01', 'YYYY-DD-MM').isValid())
console.log(` moment('2019-22-22', 'YYYY-DD-MM').isValid()?  ` +moment('2019-22-22', 'YYYY-DD-MM').isValid())
console.log(` moment('undefined', 'YYYY-DD-MM').isValid()?  ` +moment('undefined', 'YYYY-DD-MM').isValid())

 moment('2019-09-01', 'YYYY-MM-DD').isValid()?  true
 moment('2019-22-01', 'YYYY-DD-MM').isValid()?  true
 moment('2019-22-22', 'YYYY-DD-MM').isValid()?  false
 moment('undefined', 'YYYY-DD-MM').isValid()?  false
3
votes

If the date is valid then the getTime() will always be equal to itself.

var date = new Date('2019-12-12');
if(date.getTime() - date.getTime() === 0) {
    console.log('Date is valid');
} else {
    console.log('Date is invalid');
}
-3
votes

Try this one. It is not nice but it will work as long as the input is constant format from your date picker.

It is badDate coming from your picker in this example

https://jsfiddle.net/xs8tvox9/

var dateFormat = 'DD-MM-YYYY'
var badDate = "2016-10-19";

var splittedDate = badDate.split('-');

if (splittedDate.length == 3) {
  var d = moment(splittedDate[2]+"-"+splittedDate[1]+"-"+splittedDate[0], dateFormat);
  alert(d.isValid())
} else {
  //incorrectFormat
}