Date.parse()

ES1+

Parses a string representation of a date and returns the number of milliseconds since the UNIX epoch, or NaN when the string cannot be interpreted. Only the ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ and its shorter forms) is guaranteed by the ECMAScript specification; every other format is parsed in engine-specific, historically inconsistent ways.

Syntax

Date.parse(dateString)

Parameters

dateString string

A string representing a date

Return Value

number

The number of milliseconds since UNIX epoch, or NaN if invalid

Examples

JavaScript
console.log(Date.parse('2024-01-15'));
console.log(Date.parse('January 15, 2024'));
console.log(Date.parse('invalid'));
Output:
// 1705276800000 1705276800000 NaN

📌 When to Use

Use Date.parse() when you receive dates as strings, typically from a JSON API, a database export, a query parameter, or user input, and you need a numeric timestamp for comparison, sorting, or validation. It is effectively the same parser used by new Date(string), so it is also a convenient validity probe: a NaN result tells you the string is not a date your engine understands, letting you reject bad input before it propagates. It shines in validation helpers, in sorting arrays of records by an ISO date field, and in computing differences between two string dates without hand-parsing them. Restrict yourself to ISO 8601 input whenever you control the format; that is the only syntax with specified cross-engine behavior. Be deliberate about time zones: an ISO date-only string like "2024-01-15" is parsed as UTC midnight, while a date-time without an offset like "2024-01-15T09:00" is parsed in the local time zone, an asymmetry mandated by the spec that surprises almost everyone. For free-form human input ("next Tuesday", "15/01/2024") do not use Date.parse() at all; use a dedicated parsing library or a date picker component, since engine behavior for non-ISO strings is unspecified and genuinely differs.

⚠️ Common Mistakes

Assuming every browser parses the same strings the same way. Outside the ISO 8601 profile, behavior is implementation-defined: "2024/01/15", "15 Jan 2024", or "Jan 15, 2024 5pm" may parse in one engine and return NaN, or a different instant, in another. Code that works in Chrome can silently break in Safari.

Missing the UTC-versus-local asymmetry: Date.parse("2024-01-15") is UTC midnight, but Date.parse("2024-01-15T00:00") is local midnight. In any timezone west of Greenwich, the first form displayed with local getters shows January 14, producing the notorious off-by-one-day bug in forms and reports.

Not checking for NaN. Date.parse("garbage") does not throw, it returns NaN, and NaN flows silently through arithmetic: NaN > 0 is false, NaN comparisons all fail, and new Date(NaN) is an Invalid Date whose toISOString() throws. Always validate with Number.isNaN() at the boundary.

Feeding it ambiguous locale formats like "01/02/2024". Whether that means January 2 or February 1 depends on the engine's legacy heuristics, not on the user's locale, so the result can be wrong for half your users while looking correct in your own testing.

Parsing with Date.parse() and then reconstructing a Date to extract fields, when the real requirement was to keep a calendar date. Round-tripping "2024-01-15" through UTC parsing and local getters mangles the date; if you only need year, month, and day, split the string yourself or use Temporal.PlainDate.from().

✅ Best Practices

Standardize on ISO 8601 with an explicit offset everywhere: emit "2024-01-15T09:30:00Z" or "2024-01-15T09:30:00+09:00" from your backend. An explicit offset removes both the cross-engine ambiguity and the UTC/local asymmetry in one stroke.

Validate at the boundary: const t = Date.parse(input); if (Number.isNaN(t)) reject early with a clear message. Number.isNaN is safer than the global isNaN, which coerces its argument and can mask other bugs.

For date-only values that represent a calendar day (birthdays, due dates), avoid timestamp parsing entirely. Store and compare the "YYYY-MM-DD" string itself, split it into numeric parts for new Date(y, m - 1, d), or use Temporal.PlainDate, which models a day without any time zone.

Never parse the output of toLocaleString() or other formatted display strings; formatting is for humans and its output varies by ICU version. Keep a machine format (ISO or epoch milliseconds) alongside anything you display.

When you must accept messy human input, use a maintained library (date-fns parse with an explicit format token, or Luxon DateTime.fromFormat) so the accepted grammar is defined by your code rather than by whichever engine happens to run it.

⚡ Performance Notes

Parsing an ISO 8601 string is a fast, single-pass operation; engines special-case the specified format and can parse millions of short strings per second. Non-ISO strings are slower because the engine falls back to a chain of legacy heuristic parsers, and the cost varies unpredictably between engines. Date.parse(s) and new Date(s).getTime() do the same parsing work, but Date.parse avoids allocating the Date object, which matters when scanning large datasets, for example sorting ten thousand records by a date column. If you repeatedly compare the same parsed values, parse once and cache the numeric timestamps rather than re-parsing inside a sort comparator: a comparator runs O(n log n) times, so pre-parsing into a Schwartzian-transform array can cut sort time dramatically for large lists.

🌍 Real World Example

Date Input Validator

Every form that accepts a date string needs a validation gate, and this example shows the standard shape: parse once, reject NaN with an actionable error message, and derive everything else (ISO normalization, past/future checks) from the single parsed timestamp. Centralizing parsing like this prevents the classic failure mode where different screens parse the same user input differently. The same structure works for API request validation, CSV import pipelines, and admin tools that bulk-edit scheduled content.

function validateAndParseDate(dateString) {
  const timestamp = Date.parse(dateString);

  if (isNaN(timestamp)) {
    return {
      valid: false,
      error: 'Invalid date format. Please use YYYY-MM-DD.'
    };
  }

  const date = new Date(timestamp);
  const now = new Date();

  return {
    valid: true,
    timestamp,
    isoString: date.toISOString(),
    isPast: date < now,
    isFuture: date > now
  };
}

console.log(validateAndParseDate('2024-06-15'));
// { valid: true, timestamp: 1718409600000, isoString: '2024-06-15T00:00:00.000Z', isPast: false, isFuture: true }

console.log(validateAndParseDate('not a date'));
// { valid: false, error: 'Invalid date format. Please use YYYY-MM-DD.' }

Related Methods