Question
How can I distinguish a valid JavaScript Date instance from an invalid one?
const d = new Date("foo");
console.log(d.toString()); // "Invalid Date"
console.log(typeof d); // "object"
console.log(d instanceof Date); // true
I want an isValidDate function that accepts a Date instance and determines whether it represents a valid date and time, rather than only validating the original date string.
Short Answer
You will learn why an invalid date is still a Date object, how JavaScript represents invalid dates internally, and how to write reliable validation functions using getTime() and Number.isNaN().
Concept
A JavaScript Date object stores one value: a timestamp measured in milliseconds from January 1, 1970 UTC. A valid date has a finite numeric timestamp.
When construction or parsing fails, JavaScript still creates a Date object, but its internal time value is NaN (Not-a-Number). That is why all of these can be true at once:
const d = new Date("foo");
console.log(d instanceof Date); // true
console.log(typeof d); // "object"
console.log(d.getTime()); // NaN
console.log(d.toString()); // "Invalid Date"
Therefore, validating a Date instance requires two checks:
- Confirm the value is a date object.
- Confirm its timestamp is not
NaN.
This matters because invalid dates can silently travel through an application and only fail later—for example, when formatting a date, saving it to an API, or calling .
Mental Model
Think of a Date as a labelled container containing a timestamp.
- A valid
Datecontainer holds a number, such as1714521600000. - An invalid
Datecontainer still exists and still has theDatelabel, but it holdsNaNinstead of a usable timestamp.
Checking value instanceof Date verifies the label. Checking value.getTime() verifies that the container holds a real timestamp.
Syntax and Examples
Use getTime() to read the timestamp and Number.isNaN() to test whether it is invalid.
function isValidDate(value) {
return value instanceof Date && !Number.isNaN(value.getTime());
}
console.log(isValidDate(new Date("2024-05-01"))); // true
console.log(isValidDate(new Date("not a date"))); // false
console.log(isValidDate("2024-05-01")); // false
console.log(isValidDate({})); // false
getTime() returns:
- A number for valid dates.
NaNfor invalid dates.
Step by Step Execution
Consider this example:
const input = "not a date";
const date = new Date(input);
const isDateObject = date instanceof Date;
const timestamp = date.getTime();
const valid = isDateObject && !Number.isNaN(timestamp);
console.log(valid); // false
Step by step:
new Date(input)creates aDateobject even though the text cannot be parsed.date instanceof Dateistruebecause it is structurally aDateinstance.date.getTime()returnsNaNbecause the date has no valid timestamp.Number.isNaN(timestamp)istrue.- The
!operator changes that tofalse, so is .
Real World Use Cases
- API boundaries: Reject invalid
Datevalues before serializing request data. - Form handling: Validate a date produced by a date picker or conversion function before saving it.
- Database writes: Prevent invalid timestamps from being stored in records.
- Scheduling: Ensure an event, reminder, or job has a usable execution time.
- Data imports: Detect malformed dates while processing CSV files or external service responses.
For example, validate before converting to ISO format:
function serializeDate(date) {
if (!isValidDate(date)) {
throw new TypeError("Expected a valid Date instance");
}
return date.toISOString();
}
Real Codebase Usage
In production code, date validation is often placed at boundaries: when input enters a function, API handler, service, or database layer.
A guard clause keeps the main logic simple:
function createAppointment(startsAt) {
if (!isValidDate(startsAt)) {
throw new TypeError("startsAt must be a valid Date");
}
return {
startsAt: startsAt.toISOString(),
createdAt: new Date().toISOString()
};
}
For applications that receive text input, separate the two responsibilities:
- Parse or construct a
Datefrom the input. - Validate the resulting
Dateinstance.
const startsAt = new Date(userInput);
if (!isValidDate(startsAt)) {
return { error: "Enter a valid date." };
}
This makes function contracts clear: a function either accepts raw strings and parses them, or it accepts already-created, valid objects.
Common Mistakes
Checking only instanceof Date
This accepts invalid dates:
function isDate(value) {
return value instanceof Date;
}
isDate(new Date("bad input")); // true — not enough
Also test the time value.
Comparing getTime() with NaN
NaN is not equal to anything, including itself:
const date = new Date("bad input");
console.log(date.getTime() === NaN); // false
Use Number.isNaN(date.getTime()) instead.
Using global isNaN() without understanding coercion
Global converts its argument to a number first:
Comparisons
| Check | What it answers | Suitable for validity? |
|---|---|---|
typeof value === "object" | Is it broadly an object? | No |
value instanceof Date | Is it a Date from this JavaScript realm? | Only partly |
value.getTime() | What timestamp does the date hold? | Yes, with Number.isNaN() |
Date.parse(text) | Can JavaScript parse this text into a timestamp? | Useful for text, not for an existing Date |
date.toString() | How is the date displayed as text? | Not recommended for validation |
Cheat Sheet
// Standard same-realm validation
function isValidDate(value) {
return value instanceof Date && !Number.isNaN(value.getTime());
}
// Cross-realm-friendly validation
function isValidDate(value) {
try {
return !Number.isNaN(Date.prototype.getTime.call(value));
} catch {
return false;
}
}
- Valid
Date→date.getTime()is a number. - Invalid
Date→date.getTime()isNaN. new Date("invalid")is still aDateobject.
FAQ
Why is new Date("bad value") instanceof Date true?
The constructor still returns a Date object. Its internal timestamp is NaN, which marks it as invalid.
How do I check whether a JavaScript date is invalid?
Use Number.isNaN(date.getTime()). It returns true for an invalid Date.
Is date.toString() === "Invalid Date" safe?
It usually identifies an invalid date, but it is better to check the timestamp with getTime(), which directly tests the date value.
Why does date.getTime() === NaN return false?
By JavaScript rules, NaN is not equal to any value, including another NaN. Use Number.isNaN().
Should my API accept date strings or Date instances?
Either can be appropriate, but choose one contract clearly. Date strings are easier to transmit over JSON; Date instances are convenient inside JavaScript code. Validate at the boundary either way.
Mini Project
Description
Build a small appointment normalizer that accepts a Date instance, rejects invalid values, and returns a safe API-ready appointment object. This demonstrates date validation at an application boundary.
Goal
Create a function that validates an appointment start time before converting it to an ISO string.
Requirements
- Create an
isValidDatefunction that accepts a value. - Return
trueonly for validDateinstances. - Create a
createAppointmentfunction that accepts a title and start date. - Throw a
TypeErrorwhen the start date is invalid. - Return an object containing the title and an ISO-formatted start time.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.