JavaScript Date Formatting: All Valid `new Date()` String Formats Explained
The Date object is JavaScript’s built-in tool for handling dates and times, but parsing date strings with new Date(string) can be surprisingly error-prone. Browsers and environments often interpret non-standard formats differently, leading to bugs like "Invalid Date" errors or incorrect timestamps. To write reliable code, it’s critical to understand which string formats are universally valid and how JavaScript parses them.
This guide demystifies the valid string formats for new Date(), breaking down standards like ISO 8601 and RFC 2822, highlighting implementation-specific quirks, and sharing best practices to avoid common pitfalls.
Table of Contents#
- How
new Date(string)Parses Dates - ISO 8601 Formats (ECMAScript Standard)
- RFC 2822/1123 Formats (Email-Style Dates)
- Implementation-Specific Formats (Use with Caution)
- Common Pitfalls to Avoid
- Best Practices for Reliable Date Parsing
- Conclusion
- Reference
How new Date(string) Parses Dates#
When you pass a string to new Date(string), JavaScript uses the same parsing logic as Date.parse(string). Both methods convert the string into a timestamp (milliseconds since the Unix epoch, 1970-01-01T00:00:00Z). If the string is unparsable, they return Invalid Date (for new Date()) or NaN (for Date.parse()).
The key rule: only string formats defined in the ECMAScript specification are guaranteed to work across all environments. Others are "implementation-specific" (i.e., browser-dependent).
ISO 8601 Formats (ECMAScript Standard)#
ISO 8601 is the most reliable and widely supported format for date strings in JavaScript. It’s defined in the ECMAScript specification, so all modern browsers and Node.js environments parse it consistently.
Date-Only ISO 8601 Strings#
These include only the date (no time) and follow the pattern YYYY-MM-DD.
Examples:
new Date("2024-03-15"); // Valid: March 15, 2024 (local time*)
new Date("2024-12-31"); // Valid: December 31, 2024 (local time*)* Critical Note: Prior to ES2015 (ES6), ISO date-only strings like "2024-03-15" were parsed as local time. Since ES2015, they’re parsed as UTC in most environments. However, some older browsers (e.g., IE11) still use local time. To avoid ambiguity, always include a time zone (see below).
Date-Time with Time#
Add a time component using T to separate date and time: YYYY-MM-DDTHH:mm:ss (hours, minutes, seconds).
Examples:
new Date("2024-03-15T14:30:00"); // Valid: March 15, 2024, 14:30:00 (local time*)
new Date("2024-12-31T23:59:59"); // Valid: December 31, 2024, 23:59:59 (local time*)* Without a time zone, the time is interpreted as local time (your system’s time zone).
Time Zones in ISO 8601#
To avoid ambiguity, ISO 8601 supports explicit time zones:
Z: UTC (e.g.,2024-03-15T14:30Z).- Offset:
±HH:mmor±HHmm(e.g.,2024-03-15T14:30+02:00for UTC+2).
Examples:
// UTC (Z suffix)
new Date("2024-03-15T14:30Z"); // March 15, 2024, 14:30 UTC → converts to local time in output
// Time zone offset (+02:00 = UTC+2)
new Date("2024-03-15T14:30:00+02:00"); // March 15, 2024, 14:30 in UTC+2 → 12:30 UTC
// Shorthand offset (+0200 = UTC+2)
new Date("2024-03-15T14:30-0500"); // March 15, 2024, 14:30 in UTC-5 → 19:30 UTCFractional Seconds#
ISO 8601 allows fractional seconds (up to 3 decimal places for milliseconds): YYYY-MM-DDTHH:mm:ss.sss.
Example:
new Date("2024-03-15T14:30:45.123Z"); // March 15, 2024, 14:30:45.123 UTCAbbreviated ISO 8601 Formats#
JavaScript parses truncated ISO formats by filling in missing values (e.g., missing minutes default to 00).
Examples:
new Date("2024"); // January 1, 2024 (local time)
new Date("2024-03"); // March 1, 2024 (local time)
new Date("2024-03-15T14"); // March 15, 2024, 14:00:00 (local time)
new Date("2024-03-15T14:30"); // March 15, 2024, 14:30:00 (local time)Ordinal and Week Dates (Rarely Used)#
ISO 8601 includes niche formats, but support is inconsistent:
- Ordinal dates:
YYYY-DDD(day of the year, e.g.,2024-075= 75th day of 2024 → March 15). - Week dates:
YYYY-WWW-D(week and day, e.g.,2024-W12-5= 5th day of week 12 → March 15, 2024).
Example (limited support):
new Date("2024-075"); // March 15, 2024 (works in Chrome/Firefox, not in older browsers)RFC 2822/1123 Formats (Email-Style Dates)#
RFC 2822 (and its update, RFC 1123) defines date formats used in emails (e.g., Mon, 15 Mar 2024 14:30:00 GMT). These are supported by JavaScript for backward compatibility.
Structure:
[DayName, ] DD Mon YYYY HH:mm:ss TimeZone
DayName(optional): 3-letter day (e.g.,Mon,Tue).DD: Day of the month (1-31).Mon: 3-letter month (e.g.,Jan,Mar).YYYY: 4-digit year.TimeZone: TypicallyGMT,UTC, or offsets like+0200.
Examples:
new Date("Mon, 15 Mar 2024 14:30:00 GMT"); // Valid (with day name)
new Date("15 Mar 2024 14:30:00 UTC"); // Valid (without day name)
new Date("Sun, 31 Dec 2023 23:59:59 +0000"); // Valid (with offset)Note: Month/day names are case-insensitive (e.g., mar or MAR works), but 3-letter abbreviations are required.
Implementation-Specific Formats (Use with Caution)#
These formats are not defined by the ECMAScript spec but are parsed by some browsers/environments. They are unreliable across platforms (e.g., Chrome vs. Safari vs. Node.js).
1. Month/Day/Year (MM/DD/YYYY)#
Common in the U.S., but ambiguous (e.g., 03/15/2024 = March 15 in the U.S., but 3rd of March in other locales).
Example (Chrome/Firefox):
new Date("03/15/2024"); // March 15, 2024 (local time)Risk: 15/03/2024 may parse as March 15 (MM/DD) or throw "Invalid Date" (if treated as DD/MM).
2. Day-Month-Year (DD-MM-YYYY)#
Used in many non-U.S. locales, but同样 ambiguous.
Example (Firefox):
new Date("15-03-2024"); // March 15, 2024 (local time)Risk: Safari may reject this format.
3. Natural Language Dates#
Strings like March 15, 2024 or 15 March 2024 are sometimes parsed, but behavior varies.
Example (Chrome):
new Date("March 15, 2024"); // March 15, 2024 (local time)Risk: Safari may return "Invalid Date" for 15 March 2024.
Common Pitfalls to Avoid#
1. Unclear Time Zones#
ISO 8601 strings without a time zone (e.g., 2024-03-15T14:30) default to local time, which varies by user. Always include Z (UTC) or an offset (e.g., +02:00) for consistency.
2. Two-Digit Years#
JavaScript parses two-digit years (e.g., 03/15/24) as 1924 (not 2024). Use four-digit years to avoid this:
new Date("03/15/24"); // March 15, 1924 (unintended!)
new Date("03/15/2024"); // March 15, 2024 (correct)3. Browser Inconsistencies#
- Safari often rejects formats like
YYYY-MM-DD(date-only ISO) orDD-MM-YYYY. - IE11 parses ISO 8601 dates as local time (not UTC).
4. "Invalid Date" Silently Fails#
new Date("invalid") returns an Invalid Date object, but it won’t throw an error. Always validate:
const date = new Date("invalid");
if (isNaN(date.getTime())) { // Check if parsing failed
throw new Error("Invalid date string");
}Best Practices for Reliable Date Parsing#
- Stick to ISO 8601 for cross-environment consistency (e.g.,
2024-03-15T14:30:00Z). - Include Time Zones explicitly (use
Zfor UTC or±HH:mmfor offsets). - Avoid Implementation-Specific Formats like
MM/DD/YYYYorMarch 15, 2024. - Use Libraries for Complex Parsing (e.g.,
date-fns,Luxon, ordayjs) if you need to handle non-standard formats. - Validate Dates after parsing with
isNaN(date.getTime()). - Prefer UTC for Server/Client Communication (ISO 8601 with
Zavoids time zone mismatches).
Conclusion#
JavaScript’s new Date(string) relies on standardized formats like ISO 8601 and RFC 2822 for reliable parsing. While implementation-specific formats may work in some browsers, they’re a breeding ground for bugs. By prioritizing ISO 8601, explicitly handling time zones, and validating parsed dates, you can ensure your code works consistently across all environments. For complex date logic, leverage libraries to avoid reinventing the wheel.
Reference#
- ECMAScript Date.parse() Specification
- MDN: Date Object Documentation
- ISO 8601 Standard
- RFC 2822 (Internet Message Format)
- date-fns Library (for robust date parsing/formatting)