So Many Native JavaScript Date Formats
I don't know about you, but I spend most of my time dreaming about the new Temporal API. It's going to make working with dates so much better in so many ways. But for now we have Date
and Intl
and together they actually offer a lot of date and time formatting options (that's formatting, not date manipulation, which is not what this article is about).
In fact, those APIs probably have every format your project needs, so if you've added a third-party library like day.js or date-fns and you only use them for formatting, then you may be able to remove those and leverage built-in JavaScript features.
Below is a comprehensive mapping of available date and time formats* to their code starting with Date
then Intl.DateTimeFormat
and Intl.RelativeTimeFormat
:
*Examples are based on an epoch of 1714329130721
, i.e. const date = new Date(1714329130721)
Format | Code | Description |
Sun Apr 28 2024 13:32:10 GMT-0500 (Central Daylight Time) | date.toString() | Coordinated Universal Time, the default format, uses local time zone |
Sun Apr 28 2024 | date.toDateString() | Date portion of Coordinated Universal Time |
13:32:10 GMT-0500 (Central Daylight Time) | date.toTimeString() | Time portion of Coordinated Universal Time |
2024-04-28T18:32:10.721Z | date.toISOString() and JSON.stringify(date) | Simplified ISO 8601, the ISO standard date time format |
Sun, 28 Apr 2024 18:32:10 GMT | date.toUTCString() | Generalized RFC 7231 date format, uses the UTC time zone |
4/28/2024, 1:32:10 PM | date.toLocaleString() | Language-based format, uses local time zone |
4/28/2024 | date.toLocaleDateString() | Date portion of language-based format |
1:32:10 PM | date.toLocaleTimeString() | Time portion of language-based format |
4/28/2024 | new Intl.DateTimeFormat().format(date) | Language-based format, uses browser locale and local time zone by default, same format as Date().toLocaleString() but more efficient because Intl does some internally caching when doing locale lookups |
2024 | new Intl.DateTimeFormat(undefined, {year: 'numeric'}).format(date) | The full year |
24 | new Intl.DateTimeFormat(undefined, {year: '2-digit'}).format(date) | Last two digits of the year |
4 | new Intl.DateTimeFormat(undefined, {month: 'numeric'}).format(date) | The month, note this value is not zero-based like Date |
04 | new Intl.DateTimeFormat(undefined, {month: '2-digit'}).format(date) | Single digit month padded with a zero |
April | new Intl.DateTimeFormat(undefined, {month: 'long'}).format(date) | The full name of the month |
Apr | new Intl.DateTimeFormat(undefined, {month: 'short'}).format(date) | Three letter month names |
A | new Intl.DateTimeFormat(undefined, {month: 'narrow'}).format(date) | Single letter month names |
Sunday | new Intl.DateTimeFormat(undefined, {weekday: 'long'}).format(date) | The full name of the weekday |
Sun | new Intl.DateTimeFormat(undefined, {weekday: 'short'}).format(date) | Three letter weekday names |
S | new Intl.DateTimeFormat(undefined, {weekday: 'narrow'}).format(date) | Single letter weekday names |
28 | new Intl.DateTimeFormat(undefined, {day: 'numeric'}).format(date) | The day of the month |
28 | new Intl.DateTimeFormat(undefined, {day: '2-digit'}).format(date) | Single digit days are padded with zero, e.g. "01" |
1 PM | new Intl.DateTimeFormat(undefined, {hour: 'numeric'}).format(date) | The hour of the day |
01 PM | new Intl.DateTimeFormat(undefined, {hour: '2-digit'}).format(date) | Single digit hour padded with zero |
1 in the afternoon | new Intl.DateTimeFormat(undefined, {dayPeriod: 'long', hour: 'numeric'}).format(date) | Time format with period of the day |
32 | new Intl.DateTimeFormat(undefined, {minute: 'numeric'}).format(date) | The minute |
32 | new Intl.DateTimeFormat(undefined, {minute: '2-digit'}).format(date) | Single digit minutes are padded with zero, e.g. "01" |
10 | new Intl.DateTimeFormat(undefined, {second: 'numeric'}).format(date) | The second |
10 | new Intl.DateTimeFormat(undefined, {second: '2-digit'}).format(date) | Single digit seconds are padded with zero, e.g. "01" |
Apr 28, 1 in the afternoon | new Intl.DateTimeFormat(undefined, {month: 'short', day: 'numeric', hour: 'numeric', dayPeriod: 'long'}).format(date) | Custom formats based on multiple options, the number of possible formats is huge, this is what you use when there isn't another shortcut available |
4/28/2024, Central Daylight Time | new Intl.DateTimeFormat(undefined, {timeZoneName: 'long'}).format(date) | The date with full time zone name |
4/28/2024, Central Time | new Intl.DateTimeFormat(undefined, {timeZoneName: 'longGeneric'}).format(date) | The date with generic time zone name |
4/28/2024, CDT | new Intl.DateTimeFormat(undefined, {timeZoneName: 'short'}).format(date) | The date with abbreviated time zone name |
4/28/2024, CT | new Intl.DateTimeFormat(undefined, {timeZoneName: 'shortGeneric'}).format(date) | The date with short generic time zone name |
Sunday, April 28, 2024 | new Intl.DateTimeFormat(undefined, {dateStyle: 'full'}).format(date) | User-friendly date format including weekday |
April 28, 2024 | new Intl.DateTimeFormat(undefined, {dateStyle: 'long'}).format(date) | User-friendly date format |
Apr 28, 2024 | new Intl.DateTimeFormat(undefined, {dateStyle: 'medium'}).format(date) | User-friendly date format with shorter month name |
4/28/24 | new Intl.DateTimeFormat(undefined, {dateStyle: 'short'}).format(date) | Shortened date format, same as the default |
1:32:10 PM Central Daylight Time | new Intl.DateTimeFormat(undefined, {timeStyle: 'full'}).format(date) | Complete time format with time zone name |
1:32:10 PM CDT | new Intl.DateTimeFormat(undefined, {timeStyle: 'long'}).format(date) | Complete time format with abbreviated time zone name |
1:32:10 PM | new Intl.DateTimeFormat(undefined, {timeStyle: 'medium'}).format(date) | Complete time format without time zone name |
1:32 PM | new Intl.DateTimeFormat(undefined, {timeStyle: 'short'}).format(date) | Hour and minute time format |
April 28, 1:32 – 3:15 PM | new Intl.DateTimeFormat(undefined, { month: "long", day: "numeric", hour: "numeric", minute: "numeric", }).formatRange(date1, date2) | Displays a date and time sensitive range, what is shown varies based on the two dates and the options used, in this example the dates differed by a couple hours and the year was omitted |
in 1 day | new Intl.RelativeTimeFormat().format(1, 'day') | Formats a time-relative message, there are many time units available |
tomorrow | new Intl.RelativeTimeFormat(undefined, {numeric: 'auto'}).format(1, 'day') | Formats a time-relative message using a shorter variation if possible |
1 day ago | new Intl.RelativeTimeFormat().format(-1, 'day') | Past time format, note the negative time value |
in 7 days | new Intl.RelativeTimeFormat().format(7, 'day') | Formatting always uses the provided unit, i.e. 7 days is not formatted as "in 1 week" |
in 1 mo. | new Intl.RelativeTimeFormat(undefined, {style: 'short'}).format(1, 'month') | Formats the message using an abbreviated time unit |
Closely related to date and time is duration. The new Intl.DurationFormat
object (available now in Safari, Chrome, and Edge) can format durations with a wide array of options. Here’s just a fraction of what’s possible with this new formatter:
Format | Code | Description |
1 hr, 5 min | new Intl.DurationFormat('en', { style: 'short' }).format({hours: 1, minutes: 5}) | Formats the duration with shorter abbreviations for the units of time |
1 hour, 5 minutes | new Intl.DurationFormat('en', { style: 'long' }).format({hours: 1, minutes: 5}) | Formats the duration with complete words for the units of time |
0:03:12.346 | new Intl.DurationFormat('en', { style: 'digital', fractionalDigits: 3 }).format({ minutes: 3, seconds: 12, milliseconds: 345, microseconds: 600, }) | Formats the duration in digital style, great for elapsed time use cases like a stopwatch UI |
Learn more about all of these formatters on MDN at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl.