Mastering date formatting using Intl.DateTimeFormat in JavaScript
Presenting a date in a specific format often brings to mind some JavaScript libraries right away, such as moment.js
and, more recently, date-fns
. Although these libraries still satisfy very peculiar use cases, they are no longer essential for simple date formatting.
Widely supported by browsers since 2016, and currently with approximately 96% global coverage, the native Intl
API can present dates in highly elaborate formats. And most importantly, all this without adding even 1Kb to your application.
To demonstrate the simplicity of the DateTimeFormat
constructor of the Intl
API, observe the following comparison between it and the mentioned libraries:
import moment from 'moment';
import { format } from 'date-fns';
const date = new Date(2024, 3, 29, 0);
moment(date).format('M/D/YYYY');
// → 4/29/2024
format(date, 'M/d/yyyy');
// → 4/29/2024
Intl.DateTimeFormat('en-US').format(date);
// → 4/29/2024
With just this example, many advantages are already evident, but the power of Intl.DateTimeFormat
is just beginning. Notice that the first argument DateTimeFormat
receives is the locale for which you intend to format the date. If the locale is not specified, the default locale set in the browser will be used. Also, the constructor's signature receives another parameter. This additional parameter is an object that contains various options. Let's start by checking each of them.
Long Formats
If you need a date format that includes text and not just digits, look at the possibilities that the month
option offers.
const date = new Date(2024, 3, 29, 0);
const opts = { day: 'numeric', year: 'numeric' };
Intl.DateTimeFormat('en-US', { ...opts, month: 'long' }).format(date);
// → April 29, 2024
Intl.DateTimeFormat('en-US', { ...opts, month: 'short' }).format(date);
// → Apr 29, 2024
Intl.DateTimeFormat('en-US', { ...opts, month: 'narrow' }).format(date);
// → A 29, 2024
Days of the Week
If you need to include not just the day of the month, but also the day of the week, simply use the weekday
option.
const date = new Date(2024, 3, 29, 0);
const opts = { day: '2-digit', month: '2-digit', year: '2-digit' };
Intl.DateTimeFormat('en-US', { ...opts, weekday: 'long' }).format(date);
// → Monday, 04/29/24
Intl.DateTimeFormat('en-US', { ...opts, weekday: 'short' }).format(date);
// → Mon, 04/29/24
Intl.DateTimeFormat('en-US', { ...opts, weekday: 'narrow' }).format(date);
// → M, 04/29/24
Hours, Minutes, and Seconds
In addition to the day, month, and year, dates can also involve time. In this case, you can use the hour
, minute
, and second
options to determine the number of digits (numeric
or 2-digit
) to present.
const date = new Date(2024, 3, 29, 5, 30, 20);
const opts = { minute: '2-digit', second: '2-digit' };
Intl.DateTimeFormat('en-US', { ...opts, hour: 'numeric' }).format(date);
// → 5:30:20 AM
Intl.DateTimeFormat('en-US', { ...opts, hour: '2-digit' }).format(date);
// → 05:30:20 AM
Time Zone
If you need to include the time zone in the format, the timeZoneName
option can be used. See below the two possibilities offered.
const date = new Date(2024, 3, 29, 5, 30, 20);
const opts = { hour: '2-digit', minute: '2-digit', second: '2-digit' };
Intl.DateTimeFormat('en-US', { ...opts, timeZoneName: 'long' }).format(date);
// → 05:30:20 AM Pacific Daylight Time
Intl.DateTimeFormat('en-US', { ...opts, timeZoneName: 'short' }).format(date);
// → 05:30:20 AM PDT
Still dealing with time, it is possible to present the date in a different time zone than the local time. The option that performs this conversion is called timeZone
. See below the same date and time used in the example above, but formatted with the time zone of East Brazil.
const date = new Date(2024, 3, 29, 5, 30, 20);
const opts = { hour: '2-digit', minute: '2-digit', second: '2-digit' };
Intl.DateTimeFormat('en-US', { ...opts, timeZone: 'Brazil/East' }).format(date);
// → 09:30:20 AM
Tip: On Wikipedia, you can check all the time zone identifiers.
Combining the possibility of applying a specific time zone with the possibility of displaying the time zone name, we can get the following result.
const date = new Date(2024, 3, 29, 5, 30, 20);
const opts = { hour: '2-digit', minute: '2-digit', second: '2-digit' };
Intl.DateTimeFormat('en-US', {
...opts,
timeZone: 'Brazil/East',
timeZoneName: 'long'
}).format(date);
// → 09:30:20 AM Brasilia Standard Time
12 vs. 24 Hours
Finally, if you need to switch from the 12-hour to the 24-hour format or vice versa, you can use the hour12
option to force this change.
const date = new Date(2024, 3, 29, 15, 30, 20);
const opts = { hour: '2-digit', minute: '2-digit', second: '2-digit' };
Intl.DateTimeFormat('en-US', { ...opts, hour12: false }).format(date);
// → 15:30:20
Intl.DateTimeFormat('pt-BR', { ...opts, hour12: true }).format(date);
// → 03:30:20 PM
It is very likely that for calculations, comparisons, and more advanced use cases involving dates, you will still need to install a library. But if what you need is simply to present a date in a specific format, the Intl
API has a great chance of meeting your needs. If you want to learn more about this API, visit the documentation available on the Mozilla Developers Network (MDN).