Skip to content

How to Check if a Date is Valid in JavaScript

Learn reliable methods to validate JavaScript Date objects and formatted date strings, including handling edge cases like invalid days/months and rollover dates.

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

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:

  1. date instanceof Date: This first check ensures that we are working with a true Date object, not a string, number, or other type.
  2. !isNaN(date): This is the key. When a Date object is used in a numeric context (like with isNaN), 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 is false.
    • An Invalid Date object converts to NaN. isNaN(NaN) is true. By negating this with !, we get our final boolean result.

Validating a Date String (e.g., YYYY-MM-DD)

Validating a date string is a two-step process:

  1. Format Check: Does the string look correct? (e.g., ^\d{4}-\d{2}-\d{2}$).
  2. Validity Check: Does the string represent a real date? (e.g., 2023-02-29 is 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 Date object, the most robust and concise method is date 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 to YYYY-MM-DD before passing it to the new Date() constructor to ensure reliable parsing.
Navigation