orip
orip

Reputation: 75437

Detecting an "invalid date" Date instance in JavaScript

I'd like to tell the difference between valid and invalid date objects in JS, but couldn't figure out how:

var d = new Date("foo");
console.log(d.toString()); // shows 'Invalid Date'
console.log(typeof d); // shows 'object'
console.log(d instanceof Date); // shows 'true'

Any ideas for writing an isValidDate function?

Upvotes: 2186

Views: 1605973

Answers (30)

Regular Jo
Regular Jo

Reputation: 5500

Do not depend on new Date().

All of these but the last fails. They create date objects, just not on the date you expect.

console.log(new Date(2023,02,35))
console.log(new Date(2023,02,29))
console.log(new Date(2023,01,29))
console.log(new Date(2024,02,39))
console.log(new Date(Date.parse('2023-02-30')))
console.log(new Date(Date.parse('2023-02-29')))
console.log(new Date(Date.parse('2023-02-31')))
console.log(new Date(Date.parse('2023-02-32'))) // fails (null)

So I wrote a function that actually validates the date, with a few more features

type ns = number | `${number}`;
class SiteDateLib {
    static validate(_options: {
        /** two digit years will create a date in the year 19xx by native-default. This can override that. You can also change the default value of options.defaultCentury to 20 or whatever you like */
        defaultCentury?: ns,
        yearMustStartWith?: ns
    } | ns, ...parts: [year?: ns, _month?: ns, day?: ns, hour?: ns, minute?: ns, second?: ns]) {
        if (!/^\d+/.test(parts.join(''))) return null;

        const hasOptions = typeof _options === 'object';
        const options = hasOptions ? _options : {};
        options.defaultCentury = options.yearMustStartWith ?? options.defaultCentury ?? 19;

        let _year = `${hasOptions ? parts.shift() : _options}`;
        if (_year.length < 3) {
            _year = _year.padStart(4, `${options.defaultCentury}0`);
        }
        if (options.yearMustStartWith && !_year.startsWith(options.yearMustStartWith)) {
            return null;
        }

        //day cannot be 0
        if ((''+parts[1]) === '0') return null;

        const [_month, _day, hour, minute, second] = [...parts, 0, 0, 0, 0, 0].map((v) => +(v || 0));
        const day = _day || 1
        const month = _month - 1;
        const year = +_year
        const date = new Date(year, month, day, hour, minute, second);
        switch (true) {
            case date.getFullYear() !== year:
            case parts[0] && date.getMonth() !== month:
            case parts[1] && date.getDate() !== day:
            case parts[2] !== undefined && date.getHours() !== hour:
            case parts[3] !== undefined && date.getMinutes() !== minute:
            case parts[4] !== undefined && date.getSeconds() !== second:
                return null
        }
        return isNaN(+date) ? null : date;
    }
};

//test SiteDateLib.validate with bad tests like negative numbers and numbers too high...
// Good Tests
console.log('good', SiteDateLib.validate(2021, 5, 31, 23, 59, 59)?.toString()) // Should return a Date object
console.log('good', SiteDateLib.validate(4, 1, 1, 0, 0, 0)?.toString()) // Should return a Date object
console.log('good', SiteDateLib.validate(2021, 6, 15)?.toString()) // Should return a Date object
console.log('good', SiteDateLib.validate(2021, 6, 15, 14, 30)?.toString()) // Should return a Date object
console.log('good', SiteDateLib.validate(2020, 2, 29)?.toString()) // Leap year valid date, should return a Date object
console.log('good', SiteDateLib.validate(2000, 2, 29, 12, 0, 0)?.toString()) // Century leap year, should return a Date object
console.log('good', SiteDateLib.validate(2021, 11, 30)?.toString()) // End of month, should return a Date object
console.log('good', SiteDateLib.validate(2021, 7, 4, 9, 15)?.toString()) // Valid date and time, should return a Date object
console.log('good', SiteDateLib.validate(1999, 12, 31, 23, 59, 59)?.toString()) // Y2K eve, should return a Date object
console.log('good', SiteDateLib.validate({ yearMustStartWith: 19 }, 22, 3, 15, 8)?.toString()) // Valid date with hour, should return a Date object

// Bad Tests
console.log('bad', SiteDateLib.validate(2021, 2, 29, 1, 1, 1)?.toString()) // Invalid date, should return null
console.log('bad', SiteDateLib.validate(20213, 1, 32, 1, 1, 1)?.toString()) // Invalid date, should return null
console.log('bad', SiteDateLib.validate(2021, 13, 1, 1, 1, 1)?.toString()) // Invalid month, should return null
console.log('bad', SiteDateLib.validate(21, 0, 1, 1, 1, 1)?.toString()) // Invalid month, should return null
console.log('bad', SiteDateLib.validate(6, 1, 35, 1, 1, 1)?.toString()) // Invalid year, should return null
console.log('bad', SiteDateLib.validate(16, 94, 1, 1, 1, 1)?.toString()) // Invalid month, should return null
console.log('bad', SiteDateLib.validate(24, -3, 1, 1, 1, 1)?.toString()) // Invalid day, should return null
console.log('bad', SiteDateLib.validate(23, 29, 1, 1, "hour", 1, 1)?.toString()) // Invalid hour, should return null
console.log('bad', SiteDateLib.validate(2021, 1, 1, 1, "minute", 1)?.toString()) // Invalid minute, should return null
console.log('bad', SiteDateLib.validate(2021, 1, 1, 1, 1, "second")?.toString()) // Invalid seconds, should return null

Upvotes: 0

King Friday
King Friday

Reputation: 26076

const isDate = dt => String(new Date(dt)) !== 'Invalid Date'

🎉 so tonight i'm gonna party up to isDate('12/31/999999')

Upvotes: 5

Andrey Patseiko
Andrey Patseiko

Reputation: 4495

You can try something like this:

const isDate = (val) => !isNaN(new Date(val).getTime());

Upvotes: 8

Alan
Alan

Reputation: 10125

With date FNS there is the function called isExists(). It check if the date exists (Feb 31 is not supposed to exist).

Examples:

// For the valid date:
const result = isExists(2018, 0, 31)
//=> true
// For the invalid date:
const result = isExists(2018, 1, 31) 
//=> false

Documentation: https://date-fns.org/v2.30.0/docs/isExists

Upvotes: 1

Hoyeon Kim
Hoyeon Kim

Reputation: 63

Here I came up with a solution that might be helpful for those looking for a test function that can check whether it's given yyyy/mm/dd or mm/dd/yyyy also with serveral symbols such as '/', '-', '.'.

function isValidDate(dateString) {
    // Regular expression pattern for mm/dd/yyyy format
    const regTestUsa = /^(0?[1-9]|1[0-2])[\/.-](0?[1-9]|1\d|2\d|3[01])[\/.-](\d{2}|\d{4})$/;
    // Regular expression pattern for yyyy/mm/dd format
    const regTestUNiv = /^(\d{2}|\d{4})[\/.-](0?[1-9]|1[0-2])[\/.-](0?[1-9]|1\d|2\d|3[01])$/;
    const regTestYear = /^(\d{2}|\d{4})$/;

    let USAformat = ''
    let Univformat = ''
    
    if (regTestUNiv.test(dateString)) {
        Univformat = dateString
    } else if (regTestUsa.test(dateString)){
        USAformat = dateString
    } else {
        return dateString instanceof Date && !isNaN(dateString);
    }

    let year = '';
    let month = '';
    let day = '';
    
    if (USAformat.length > 0){
         [month,day,year] = USAformat.split(/[\/.-]/);
    } else if(Univformat.length > 0){
         [year,month,day] = Univformat.split(/[\/.-]/)
    }

    const parsedYear = parseInt(year, 10);
    if (parsedYear < 100) {
        // Adjust 2-digit year to 4-digit year
        const currentYear = new Date().getFullYear();
        const currentCentury = Math.floor(currentYear / 100) * 100;
        const adjustedYear = currentCentury + parsedYear;

        if (!regTestYear.test(adjustedYear)) {
            return false;
        }
    }

    const date = new Date(year, month - 1, day);
    if (isNaN(date.getTime())) {
        return false;
    }

    const parsedMonth = date.getMonth() + 1;
    const parsedDay = date.getDate();

    return (
        parseInt(month, 10) === parsedMonth &&
        parseInt(day, 10) === parsedDay
    );
}

you can test codes with the followings:

// Is the date valid Date object
console.log(isValidDate(new Date()), "T")

// Does the date start with 0 for month and/or day 
console.log(isValidDate('2023.01.21'),"T") // true
console.log(isValidDate('2023.01.09'),"T") // true
console.log(isValidDate('2023.1.09'),"T") // true

// Is the date divided by valid symble
console.log(isValidDate('2023/12/31'),"T")  // true
console.log(isValidDate('2023-12-31'),"T") // true
console.log(isValidDate('2023.12.31'),"T") // true
console.log(isValidDate('2023?12.31'),"F") // false

// Is the date formatted in USA 
console.log(isValidDate('12/31/2050'),"T") // true
console.log(isValidDate('12/31/50'),"T") // true

// Is the date out of range
console.log(isValidDate('2023.2.29'),"F")  // false
console.log(isValidDate('2023.14.29'),"F")  // false
console.log(isValidDate('2023.01.32'),"F") // false

//other test
console.log(isValidDate('12/0/0'),"F")
console.log(isValidDate('0/0/0'),"F")
console.log(isValidDate('/120/0'),"F")
console.log(isValidDate('boo'),"F")
console.log(isValidDate('124'),"F")
 

Upvotes: 0

Jordan Szymczyk
Jordan Szymczyk

Reputation: 85

NaN is falsy. invalidDateObject.valueOf() is NaN.

const d = new Date('foo');
if (!d.valueOf()) {
  console.error('Not a valid date object');
}
else {
  // act on your validated date object
}

Even though valueOf() is functionally equivelant to getTime(), I feel it's more appropriate in this context.

Upvotes: 4

Steven Spungin
Steven Spungin

Reputation: 29071

After reading every answer so far, I am going to offer the most simple of answers.

Every solution here mentions calling date.getTime(). However, this is not needed, as the default conversion from Date to Number is to use the getTime() value. Yep, your type checking will complain. :) And the OP cleary knows they have a Date object, so no need to test for that either.

To test for an invalid date:

isNaN(date)

To test for a valid date:

!isNaN(date)

or (thanks to icc97 for this alternative)

isFinite(date) 

or typescript (thanks to pat-migliaccio)

isFinite(+date) 

Upvotes: 75

Petr Kloza
Petr Kloza

Reputation: 53

Only a few people here (@Zen, @Dex, @wanglab...) counts with a javascript tolerance of overflowing the day number in months like February, April, June, etc...

If you specify which format you would like to handle (i.e. yyyy-MM-dd), then you do not have to use the javascript object Date at all in your solution.

function leapYear(year) {
    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

function validateDateStr(dateStr) {

    if (/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$/.test(dateStr) === false) {
        return false;
    }

    var m = parseInt(dateStr.substr(5, 2));
    var d = parseInt(dateStr.substr(8, 2));
    var y = parseInt(dateStr.substr(0, 4));

    // you can add a year check for a value greater than let's say 5000 :-D

    if (m > 12 || d > 31) {
        return false;
    } else if (m == 2 && d > 28) {
        if (d == 29) {
            if (!leapYear(y)) {
                return false;
            }
        } else {
            return false;
        }
    } else if (d > 30 && (m == 4 || m == 6 || m == 9 || m == 11)) {
        return false;
    }

    return true;
}

console.log("2020-02-29:" + validateDateStr("2020-02-29")); // true
console.log("2020-02-30:" + validateDateStr("2020-02-30")); // false
console.log("2022-02-29:" + validateDateStr("2022-02-29")); // false
console.log("2021-02-28:" + validateDateStr("2021-02-28")); // true
console.log("2020-03-31:" + validateDateStr("2020-03-31")); // true
console.log("2020-04-30:" + validateDateStr("2020-04-30")); // true
console.log("2020-04-31:" + validateDateStr("2020-04-31")); // false
console.log("2020-07-31:" + validateDateStr("2020-07-31")); // true
console.log("2020-07-32:" + validateDateStr("2020-07-32")); // false
console.log("2020-08-31:" + validateDateStr("2020-08-31")); // true
console.log("2020-12-03:" + validateDateStr("2020-12-03")); // true
console.log("2020-13-03:" + validateDateStr("2020-13-03")); // false
console.log("0020-12-03:" + validateDateStr("0020-12-03")); // true
//invalid regex
console.log("20-12-03:" + validateDateStr("20-12-03")); // false
console.log("2020-012-03:" + validateDateStr("2020-012-03")); // false
console.log("2020-12-003:" + validateDateStr("2020-12-003")); // false

Upvotes: 2

Vijay Jagdale
Vijay Jagdale

Reputation: 2649

Why am I writing a 48th answer after so many have tried before me? Most of the answers are partly correct and will not work in every situation, while others are unnecessarily verbose and complex. Below is a very concise solution. This will checking if it is Date type and then check if a valid date object:

return x instanceof Date && !!x.getDate();

Now for parsing date Text: Most of the solutions use Date.parse(), or "new Date()" -- both of these will fail certain situations and can be dangerous. JavaScript parses a wide variety of formats and also is dependent on localization. For example, strings like "1" and "blah-123" will parse as a valid date.

Then there are posts that either use a ton of code, or a mile-long RegEx, or use third party frameworks.

This is dead simple method to validate a date string.

function isDate(txt) {
   var matches = txt.match(/^\d?\d\/(\d?\d)\/\d{4}$/); //Note: "Day" in the RegEx is parenthesized
   return !!matches && !!Date.parse(txt) && new Date(txt).getDate()==matches[1];
}
TEST THE FUNCTION
<br /><br />
<input id="dt" value = "12/21/2020">
<input type="button" value="validate" id="btnAction" onclick="document.getElementById('rslt').innerText = isDate(document.getElementById('dt').value)"> 
<br /><br />
Result: <span id="rslt"></span>

The first line of isDate parses the input text with a simple RegEx to validate for date formats mm/dd/yyyy, or m/d/yyyy. For other formats, you will need to change the RegEx accordingly, e.g. for dd-mm-yyyy the RegEx becomes /^(\d?\d)-\d?\d-\d{4}$/

If parse fails, "matches" is null, otherwise it stores the day-of-month. The second lines does more tests to ensure it is valid date and eliminates cases like 9/31/2021 (which JavaScript permits). Finally note the double-whack (!!) converts "falsy" to a boolean false.

Upvotes: 17

Greg Finzer
Greg Finzer

Reputation: 7054

This flavor of isValidDate uses a regular expression that handles leap years. It works on regular dates, but not iso ones:

function isValidDate(value) {
  return /((^(10|12|0?[13578])([/])(3[01]|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(11|0?[469])([/])(30|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(2[0-8]|1[0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(29)([/])([2468][048]00)$)|(^(0?2)([/])(29)([/])([3579][26]00)$)|(^(0?2)([/])(29)([/])([1][89][0][48])$)|(^(0?2)([/])(29)([/])([2-9][0-9][0][48])$)|(^(0?2)([/])(29)([/])([1][89][2468][048])$)|(^(0?2)([/])(29)([/])([2-9][0-9][2468][048])$)|(^(0?2)([/])(29)([/])([1][89][13579][26])$)|(^(0?2)([/])(29)([/])([2-9][0-9][13579][26])$))/.test(value)
}

function test(value) {
  console.log(`${value} valid: ${isValidDate(value)}`)
}
<button onClick="test('foo')">foo</button>
<button onClick="test('2/20/2000')">2/20/2000</button>
<button onClick="test('20/2/2000')">20/2/2000</button>
<button onClick="test('2022-02-02T18:51:53.517Z')">2022-02-02T18:51:53.517Z</button>

Upvotes: 3

Borgar
Borgar

Reputation: 38644

Here's how I would do it:

if (Object.prototype.toString.call(d) === "[object Date]") {
  // it is a date
  if (isNaN(d)) { // d.getTime() or d.valueOf() will also work
    // date object is not valid
  } else {
    // date object is valid
  }
} else {
  // not a date object
}

Update [2018-05-31]: If you are not concerned with Date objects from other JS contexts (external windows, frames, or iframes), this simpler form may be preferred:

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}

Update [2021-02-01]: Please note that there is a fundamental difference between "invalid dates" (2013-13-32) and "invalid date objects" (new Date('foo')). This answer does not deal with validating date input, only if a Date instance is valid.

Upvotes: 1868

Jason Foglia
Jason Foglia

Reputation: 2521

I have seen some answers that came real close to this little snippet.

JavaScript way:

function isValidDate(dateObject){
    return new Date(dateObject).toString() !== 'Invalid Date';
}
console.log(isValidDate('WTH')); // -> false
console.log(isValidDate(new Date('WTH'))); // -> false
console.log(isValidDate(new Date())); // -> true

ES2015 way:

const isValidDate = dateObject => new Date(dateObject)
    .toString() !== 'Invalid Date';
console.log(isValidDate('WTH')); // -> false
console.log(isValidDate(new Date('WTH'))); // -> false
console.log(isValidDate(new Date())); // -> true

Upvotes: 61

LocV&#39;s Nest
LocV&#39;s Nest

Reputation: 118

I have a solution.

const isInvalidDate = (dateString) => JSON.stringify(new Date(dateString)) === 'null';

const invalidDate = new Date('Hello');
console.log(isInvalidDate(invalidDate)); //true

const validDate = new Date('2021/02/08');
console.log(isInvalidDate(validDate)); //false

Upvotes: 1

iClyde
iClyde

Reputation: 26

Try something like this:

if (!('null' === JSON.stringify(new Date('wrong date')))) console.log('correct');
else console.log('wrong');

Upvotes: 0

Carsten F&#252;hrmann
Carsten F&#252;hrmann

Reputation: 3490

I rarely recommend libraries when one can do without. But considering the plethora of answers so far it seems worth pointing out that the popular library "date-fns" has a function isValid. The following documentation is taken from their website:

isValid argument Before v2.0.0 v2.0.0 onward
new Date() true true
new Date('2016-01-01') true true
new Date('') false false
new Date(1488370835081) true true
new Date(NaN) false false
'2016-01-01' TypeError false
'' TypeError false
1488370835081 TypeError true
NaN TypeError false

Upvotes: 10

Raz
Raz

Reputation: 605

Inspired by Borgar's approach I made sure that the code not only validates the date, but actually makes sure the date is a real date, meaning that dates like 31/09/2011 and 29/02/2011 are not allowed.

function(dateStr) {
  s = dateStr.split('/');
  d = new Date(+s[2], s[1] - 1, +s[0]);
  if (Object.prototype.toString.call(d) === "[object Date]") {
    if (!isNaN(d.getTime()) && d.getDate() == s[0] &&
      d.getMonth() == (s[1] - 1)) {
      return true;
    }
  }
  return "Invalid date!";
}

Upvotes: 4

Dmytro Shevchenko
Dmytro Shevchenko

Reputation: 34581

I wrote the following solution based on Borgar's solution. Included in my library of auxiliary functions, now it looks like this:

Object.isDate = function(obj) {
/// <summary>
/// Determines if the passed object is an instance of Date.
/// </summary>
/// <param name="obj">The object to test.</param>

    return Object.prototype.toString.call(obj) === '[object Date]';
}

Object.isValidDate = function(obj) {
/// <summary>
/// Determines if the passed object is a Date object, containing an actual date.
/// </summary>
/// <param name="obj">The object to test.</param>

    return Object.isDate(obj) && !isNaN(obj.getTime());
}

Upvotes: 9

John
John

Reputation: 3546

None of the above solutions worked for me what did work however is

function validDate (d) {
    var date = new Date(d);
    var day = "" + date.getDate();
    if ( day.length == 1 ) day = "0" + day;
    var month = "" + (date.getMonth() + 1);
    if ( month.length == 1 ) month = "0" + month;
    var year = "" + date.getFullYear();
    return (( month + "/" + day + "/" + year ) == d );
}

the code above will see when JS makes 02/31/2012 into 03/02/2012 that it's not valid

Upvotes: 4

Balaji
Balaji

Reputation: 10877

Why i Suggest moment.js

it is very popular library

simple to solve all date and time,format,timezone problems

easy to check string date valid or not

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

we can't solve simple way to validate all the cases

Disspointment

if i insert in valid number like 89,90,95 in new Date() above few answare , i am getting bad result however it return true

const isValidDate = date => { 
console.log('input'+date)
var date=new Date(date);

console.log(date)
return !! (Object.prototype.toString.call(date) === "[object Date]" && +date)
//return !isNaN(date.getTime())
}


var test="05/04/2012"
console.log(isValidDate(test))



var test="95"
console.log(isValidDate(test))



var test="89"
console.log(isValidDate(test))



var test="80"
console.log(isValidDate(test))



var test="badstring"
console.log(isValidDate(test))

Upvotes: -1

S. Esteves
S. Esteves

Reputation: 453

Pure JavaScript solution:

const date = new Date(year, (+month-1), day);
const isValidDate = (Boolean(+date) && date.getDate() == day);

Also works on leap years!

Credit to https://medium.com/@esganzerla/simple-date-validation-with-javascript-caea0f71883c

Upvotes: 0

Stefan Rein
Stefan Rein

Reputation: 9036

No one has mentioned it yet, so Symbols would also be a way to go:

Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date") // true

Symbol.for(new Date()) === Symbol.for("Invalid Date") // false

console.log('Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date")', Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date")) // true

console.log('Symbol.for(new Date()) === Symbol.for("Invalid Date")', Symbol.for(new Date()) === Symbol.for("Invalid Date")) // false

Be aware of: https://caniuse.com/#search=Symbol

Upvotes: 3

duan
duan

Reputation: 8845

If you use io-ts, you can use the decoder DateFromISOString directly.

import { DateFromISOString } from 'io-ts-types/lib/DateFromISOString'

const decoded = DateFromISOString.decode('2020-05-13T09:10:50.957Z')

Upvotes: 0

Soubriquet
Soubriquet

Reputation: 3330

Simple and elegant solution:

const date = new Date(`${year}-${month}-${day} 00:00`)
const isValidDate = (Boolean(+date) && date.getDate() == day)

sources:

[1] https://medium.com/@esganzerla/simple-date-validation-with-javascript-caea0f71883c

[2] Incorrect date shown in new Date() in JavaScript

Upvotes: 4

iwatakeshi
iwatakeshi

Reputation: 697

Yet another way to check whether the date is a valid date object:

const isValidDate = (date) => 
  typeof date === 'object' && 
  typeof date.getTime === 'function' && 
  !isNaN(date.getTime())

Upvotes: 1

wanglabs
wanglabs

Reputation: 47

This function validates a string date in digit formats delimited by a character, e.g. dd/mm/yyyy, mm/dd/yyyy

/*
Param  : 
1)the date in string data type 
2)[optional - string - default is "/"] the date delimiter, most likely "/" or "-"
3)[optional - int - default is 0] the position of the day component when the date string is broken up via the String.split function (into arrays)
4)[optional - int - default is 1] the position of the month component when the date string is broken up via the String.split function (into arrays)
5)[optional - int - default is 2] the position of the year component when the date string is broken up via the String.split function (into arrays)

Return : a javascript date is returned if the params are OK else null
*/
function IsValidDate(strDate, strDelimiter, iDayPosInArray, iMonthPosInArray, iYearPosInArray) {
    var strDateArr; //a string array to hold constituents day, month, and year components
    var dtDate; //our internal converted date
    var iDay, iMonth, iYear;


    //sanity check 
    //no integer checks are performed on day, month, and year tokens as parsing them below will result in NaN if they're invalid
    if (null == strDate || typeof strDate != "string")
        return null;

    //defaults
    strDelimiter = strDelimiter || "/";
    iDayPosInArray = undefined == iDayPosInArray ? 0 : iDayPosInArray;
    iMonthPosInArray = undefined == iMonthPosInArray ? 1 : iMonthPosInArray;
    iYearPosInArray = undefined == iYearPosInArray ? 2 : iYearPosInArray;

    strDateArr = strDate.split(strDelimiter);

    iDay = parseInt(strDateArr[iDayPosInArray],10);
    iMonth = parseInt(strDateArr[iMonthPosInArray],10) - 1; // Note: months are 0-based
    iYear = parseInt(strDateArr[iYearPosInArray],10);

    dtDate = new Date(
        iYear,
        iMonth, // Note: months are 0-based
        iDay);

    return (!isNaN(dtDate) && dtDate.getFullYear() == iYear && dtDate.getMonth() == iMonth && dtDate.getDate() == iDay) ? dtDate : null; // Note: months are 0-based
}

Example call:

var strDate="18-01-1971";

if (null == IsValidDate(strDate)) {

  alert("invalid date");
}

Upvotes: 0

saaj
saaj

Reputation: 25174

Date.prototype.toISOString throws RangeError (at least in Chromium and Firefox) on invalid dates. You can use it as a means of validation and may not need isValidDate as such (EAFP). Otherwise it's:

function isValidDate(d)
{
  try
  {
    d.toISOString();
    return true;
  }
  catch(ex)
  {
    return false;    
  }    
}

Upvotes: 7

rainabba
rainabba

Reputation: 4267

date.parse(valueToBeTested) > 0 is all that's needed. A valid date will return the epoch value and an invalid value will return NaN which will fail > 0 test by virtue of not even being a number.

This is so simple that a helper function won't save code though it might be a bit more readable. If you wanted one:

String.prototype.isDate = function() {
  return !Number.isNaN(Date.parse(this));
}

OR

To use:

"StringToTest".isDate();

Upvotes: -1

Ash
Ash

Reputation: 62096

Instead of using new Date() you should use:

var timestamp = Date.parse('foo');

if (isNaN(timestamp) == false) {
  var d = new Date(timestamp);
}

Date.parse() returns a timestamp, an integer representing the number of milliseconds since 01/Jan/1970. It will return NaN if it cannot parse the supplied date string.

Upvotes: 377

Yuseferi
Yuseferi

Reputation: 8670

you can check the valid format of txDate.value with this scirpt. if it was in incorrect format the Date obejct not instanced and return null to dt .

 var dt = new Date(txtDate.value)
 if (isNaN(dt))

And as @MiF's suggested in short way

 if(isNaN(new Date(...)))

Upvotes: 19

Sebastien H.
Sebastien H.

Reputation: 7116

Too many complicated answers here already, but a simple line is sufficient (ES5):

Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;

or even in ES6 :

Date.prototype.isValid = d => !isNaN(Date.parse(d));

Upvotes: 15

Related Questions