How to Check if a Date is Valid in JavaScript
Validating dates is a common requirement in JavaScript, whether you're working with Date objects directly or parsing date strings from user input. A "valid" date means two different things: a Date object that represents a real calendar date, or a string that correctly conforms to a specific format like YYYY-MM-DD.
This guide will teach you the modern, standard method for validating a Date object. It will also show you a robust technique for validating date strings by checking both their format and their calendar correctness (e.g., ensuring the day is not 32).
The Core Problem: new Date() Can Create "Invalid Date"
A frequent source of confusion is that the new Date() constructor does not throw an error when given invalid input. Instead, it creates a special Date object whose internal value is Invalid Date.
Example of code with problems
// Problem: This operation does not throw errors; it creates an Invalid Date.
let invalidDate1 = new Date('not-a-date');
console.log(invalidDate1); // Output: Invalid Date
You cannot perform any useful operations on an Invalid Date object. Calling getTime() on it returns NaN. Our goal is to create a function that can reliably detect this state.
Validating a Date Object
The simplest and most robust way to check if a Date object is valid is to check if its time value is not NaN (Not-a-Number).
This function checks two things: that the input is actually an instance of the Date object and that its internal time value is a valid number.
/**
* Checks if the provided value is a valid Date object.
* @param {*} date - The value to check.
* @returns {boolean} True if the value is a valid Date.
*/
function isValidDate(date) {
return date instanceof Date && !isNaN(date);
}
// Example Usage:
console.log(isValidDate(new Date())); // Output: true
console.log(isValidDate(new Date('2025-10-27'))); // Output: true
console.log(isValidDate(new Date('not-a-date'))); // Output: false
console.log(isValidDate('2025-10-27')); // Output: false (it's a string, not a Date object)
How It works:
date instanceof Date: This first check ensures that we are working with a trueDateobject, not a string, number, or other type.!isNaN(date): This is the key. When aDateobject is used in a numeric context (like withisNaN), it is converted to its time value (a timestamp in milliseconds).- A valid date converts to a large integer (e.g.,
1698384000000).isNaN()on this number isfalse. - An
Invalid Dateobject converts toNaN.isNaN(NaN)istrue. By negating this with!, we get our final boolean result.
- A valid date converts to a large integer (e.g.,
Validating a Date String (e.g., YYYY-MM-DD)
Validating a date string is a two-step process:
- Format Check: Does the string look correct? (e.g.,
^\d{4}-\d{2}-\d{2}$). - Validity Check: Does the string represent a real date? (e.g.,
2023-02-29is invalid).
This function combines a regular expression with the Date object's parsing behavior to perform a robust check.
/**
* Checks if a string is a valid date in YYYY-MM-DD format.
* @param {string} dateString - The string to check.
* @returns {boolean} True if the string is a valid date.
*/
function isValidDateString(dateString) {
let regex = /^\d{4}-\d{2}-\d{2}$/;
// 1. Check the format
if (!dateString.match(regex)) {
return false;
}
// 2. Parse the date and check for invalid values
let date = new Date(dateString);
let timestamp = date.getTime();
if (isNaN(timestamp)) {
return false;
}
// 3. Re-format the date to ISO and compare, to catch rollover issues
return date.toISOString().startsWith(dateString);
}
// Example Usage:
console.log(isValidDateString('2023-10-27')); // Output: true
console.log(isValidDateString('2025-02-29')); // Output: false (2025 is not a leap year)
console.log(isValidDateString('2023-13-01')); // Output: false (invalid month)
console.log(isValidDateString('not-a-date')); // Output: false
How the Date String Validation Works
The final check, date.toISOString().startsWith(dateString), is a clever trick to catch "rollover" dates. If you give new Date() an invalid day or month, like 2025-02-30, it doesn't become an Invalid Date. Instead, it "rolls over" to the next valid date, 2025-03-02. By converting this rolled-over date back to an ISO string (YYYY-MM-DD...) and checking if it still starts with our original input, we can detect if a rollover occurred. If it did, the original date string was not valid.
Validating Other String Formats (e.g., MM/DD/YYYY)
The new Date() letructor is notoriously unreliable at parsing formats other than YYYY-MM-DD. To validate other formats, you must first reformat the string into the YYYY-MM-DD standard before parsing.
Solution:
function isValidMMDDYYYY(dateString) {
let regex = /^\d{2}\/\d{2}\/\d{4}$/;
if (!dateString.match(regex)) return false;
// Reformat to YYYY-MM-DD
let [month, day, year] = dateString.split('/');
let isoFormattedString = `${year}-${month}-${day}`;
// Now, use the same validation logic as before
let date = new Date(isoFormattedString);
let timestamp = date.getTime();
if (isNaN(timestamp)) return false;
return date.toISOString().startsWith(isoFormattedString);
}
console.log(isValidMMDDYYYY('10/27/2023')); // Output: true
console.log(isValidMMDDYYYY('02/29/2023')); // Output: false
Conclusion
Validating dates in JavaScript requires different approaches for Date objects and date strings.
- To validate a
Dateobject, the most robust and concise method isdate instanceof Date && !isNaN(date). - To validate a date string, you must perform a two-part check: first, use a regular expression to validate the format, and second, parse the string and check its calendar validity, preferably by checking for date rollovers.
- For any string format other than
YYYY-MM-DD, always reformat the string toYYYY-MM-DDbefore passing it to thenew Date()constructor to ensure reliable parsing.