207

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.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Ganesh
  • 5,977
  • 5
  • 19
  • 25
  • 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 Oct 19 '16 at 06:38
  • The input is coming from date picker. Can't change that too :( – Ganesh Oct 19 '16 at 06:41
  • 1
    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 concerned – Pochen Oct 19 '16 at 06:43
  • really can't say. But that is not in my control to change that value. – Ganesh Oct 19 '16 at 06:44
  • 2
    Possible duplicate of [How to test a string is valid date or not using moment?](http://stackoverflow.com/questions/28227862/how-to-test-a-string-is-valid-date-or-not-using-moment) – Luca Fagioli May 11 '17 at 15:39

12 Answers12

272

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.

Ganesh
  • 5,977
  • 5
  • 19
  • 25
  • 22
    Does anyone know what the current preferred method is now? This method now throws the following "Deprecation Warning": moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info. – Andrew Sep 07 '18 at 23:53
  • 1
    @Andrew Please look at https://stackoverflow.com/questions/23263380/deprecation-warning-moment-construction-falls-back-to-js-date, https://github.com/moment/moment/issues/2535 – Ganesh Sep 10 '18 at 05:27
  • 11
    Just a heads up that this doesn't always work: `var a = moment('12345'); a.isValid() // is true` This fails because moment will fall back to the default date object if it can't parse the date. And the default date object will always return a date (just not the one you want.) – Mauvis Ledford Oct 24 '18 at 22:50
  • That Github thread, the first comments outlines why it's deprecated but doesn't provide an alternative for checking invalid dates. When using `moment('1234').isValid()` as documented it still throws a deprecation notice. – png Nov 21 '18 at 21:31
  • 5
    need to add that `moment('02').isValid() === true`, so you might want to be careful with that – Bruno Finger Dec 03 '18 at 13:53
  • 4
    Also `moment('abcde 1').isValid() === true` – Amiram Korach Jan 02 '19 at 09:08
  • Warning: isValid() is not in any way reliable without a format. Do not be burnt – zanderwar Jun 26 '19 at 04:21
  • 5
    This is a wrong answer because I always get true whatever string I pass in – Billal Begueradj Jan 24 '20 at 08:06
  • var date = moment("2016-10-32") this is not valid date but it is returning date is valid – dev verma Jul 28 '20 at 09:51
  • Also `moment(undefined).isValid() === true` (?) – Pablo Lammel Aug 19 '22 at 14:37
163

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.

Andrew
  • 1,717
  • 1
  • 10
  • 8
47

I just found a really messed up case.

moment('Decimal128', 'YYYY-MM-DD').isValid() // true
Sam Araiza
  • 796
  • 8
  • 12
23

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 I: `new Date()` circumvents the warning that
//   Moment throws (https://momentjs.com/guides/#/warnings/js-date/),
//   but may not be optimal.

// Note II: passing `true` as third argument to `moment()` enables strict-mode
//   https://momentjs.com/guides/#/parsing/strict-mode/

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

tim-montague
  • 16,217
  • 5
  • 62
  • 51
22

Here you go: Working Fidddle

$(function(){
  var dateFormat = 'DD-MM-YYYY';
  alert(moment(moment("2012-10-19").format(dateFormat),dateFormat,true).isValid());
});
gschambial
  • 1,383
  • 2
  • 11
  • 22
19

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

Moshe Slavin
  • 5,127
  • 5
  • 23
  • 38
wakeupoj
  • 190
  • 1
  • 5
8
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
Sande
  • 313
  • 3
  • 7
  • 2
    could you please add some explanation to your answer? What additional value does this add to the already existing and accepted answer? – slfan May 21 '19 at 07:08
6

What I have used is moment.js

let value = '19-05-1994';
let check = moment(value,'DD-MM-YYYY', true).isValid();
        console.log(check) //returns true
        return check
oluwatyson
  • 251
  • 4
  • 18
4

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');
}
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Tanzeem Bhatti
  • 219
  • 2
  • 3
1

You can use

var d = moment("2016-10-19",dateFormat);
if(!isNaN(d)) {
  // d is a valid date.
}
Erisan Olasheni
  • 2,395
  • 17
  • 20
0
moment("2022-10-18 04:00 AM", "YYYY-MM-DD HH:mm AM", true).isValid()
starball
  • 20,030
  • 7
  • 43
  • 238
Ashish
  • 33
  • 6
-3

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
}
Phil3992
  • 1,059
  • 6
  • 21
  • 45
Pochen
  • 2,871
  • 3
  • 22
  • 27