Validate a Date String in JavaScript

To validate a date string, parse it with Temporal.PlainDate.from (or Instant.from) inside a try/catch — it throws on anything malformed, unlike new Date(), which sometimes returns a wrong date instead of failing. Part of Parsing ISO 8601 Strings Safely.

Why this scenario is tricky

new Date(str) is a poor validator: it returns Invalid Date for some junk but happily reinterprets other junk ('2024-02-31' becomes 2 March in some engines, '01/02/2024' is ambiguous). Real validation means rejecting anything that is not exactly the format you accept, which is what Temporal's strict from() does.

new Date accepts too muchIt coerces some invalid input instead of failingnew Date accepts too muchnew Date('2024-02-31')rolls over to MarchPlainDate.from('2024-02-31')throws RangeErrorStrict from() rejects impossible dates; Date silently normalizes them.

Minimal working solution

import { Temporal } from '@js-temporal/polyfill';
function isValidDate(s: string): boolean {
  try { Temporal.PlainDate.from(s, { overflow: 'reject' }); return true; }
  catch { return false; }
}

Strict validationfrom() with overflow reject is the testStrict validationstringPlainDate.fromrejecttrue / false

Full production version

import { Temporal } from '@js-temporal/polyfill';
// Return the parsed value or a typed error, not just a boolean.
function parseDate(s: string): Temporal.PlainDate {
  try { return Temporal.PlainDate.from(s, { overflow: 'reject' }); }
  catch { throw new TypeError(`Not a valid ISO date: ${s}`); }
}

Parse or throwReturn the value or a typed errorParse or throwinputfrom rejectcatchvalue / error

Verification snippet

Validate a Date String in JavaScript — assertionsKey cases assert correctlyAssertions that prove the edge case'2024-03-15'valid'2024-02-31'invalid'2024-13-01'invalid'03/15/2024'invalid

Common pitfalls

Validate a Date String pitfallsCommon mistakes and their fixesWrongRightnew Date() NaN check onlymisses rolled-over datesTemporal.from overflow rejectrejects impossible datesaccept slashes/2-digit yearsambiguousrequire full ISO 8601unambiguous

Frequently Asked Questions

How do I properly validate a date string?

Parse it with Temporal.PlainDate.from(s, { overflow: 'reject' }) inside a try/catch. It throws on malformed strings and on impossible dates like 2024-02-31, so a successful parse means the string is genuinely a valid ISO date.

Why is new Date() not enough to validate a date?

new Date() returns Invalid Date for some inputs but silently reinterprets others — 2024-02-31 rolls into March, and slash formats are engine-specific — so a non-NaN result does not guarantee the input was valid. Strict Temporal parsing rejects both cases.