Date and time formatting
The formatting of dates and times varies greatly between locales (e.g. "Apr 24, 2023" in en-US
vs. "24 квіт. 2023 р." in uk-UA
). By using the formatting capabilities of next-intl
, you can handle i18n differences in your Next.js app automatically.
Formatting dates and times
You can format plain dates that are not part of a message with the dateTime
function that is returned from the useFormatter
hook:
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTime = new Date('2020-11-20T10:36:01.516Z');
// Renders "Nov 20, 2020"
format.dateTime(dateTime, {
year: 'numeric',
month: 'short',
day: 'numeric'
});
// Renders "11:36 AM"
format.dateTime(dateTime, {hour: 'numeric', minute: 'numeric'});
}
See the MDN docs about DateTimeFormat
(opens in a new tab) to learn more about the options that you can provide to the dateTime
function or try the interactive explorer for Intl.DateTimeFormat
(opens in a new tab).
How can I parse dates or manipulate them?
Since next-intl
is only concerned with formatting dates, you can use a library like date-fns (opens in a new tab) to manipulate them.
To parse dates, you can pass them to the Date
constructor (opens in a new tab).
import {subDays} from 'date-fns';
// Make sure your date string conforms to ISO 8601
const date = new Date('2020-11-20T10:36:01.516Z');
// 2020-11-18T10:36:01.516Z
const twoDaysAgo = subDays(date, 2);
Formatting relative time
You can format plain dates that are not part of a message with the relativeTime
function:
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTime = new Date('2020-11-20T08:30:00.000Z');
// At 2020-11-20T10:36:00.000Z,
// this will render "2 hours ago"
format.relativeTime(dateTime);
}
Note that values are rounded, so e.g. if 126 minutes have passed, "2 hours ago" will be returned.
Supplying now
By default, relativeTime
will use the global value for now
. If you want to use a different value, you can explicitly pass this as the second parameter.
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTime = new Date('2020-11-20T08:30:00.000Z');
const now = new Date('2020-11-20T10:36:00.000Z');
// Renders "2 hours ago"
format.relativeTime(dateTime, now);
}
If you want the relative time value to update over time, you can do so with the useNow
hook:
import {useNow, useFormatter} from 'next-intl';
function Component() {
// Use the global now value initially …
const now = useNow({
// … and update it every 10 seconds
updateInterval: 1000 * 10
});
const format = useFormatter();
const dateTime = new Date('2020-11-20T10:36:01.516Z');
// Renders e.g. "2 hours ago" and updates continuously
format.relativeTime(dateTime, now);
}
Customizing the unit
By default, relativeTime
will pick a unit based on the difference between the passed date and now
(e.g. 3 seconds, 40 minutes, 4 days, etc.).
If you want to use a specific unit, you can provide options via the second argument:
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTime = new Date('2020-03-20T08:30:00.000Z');
const now = new Date('2020-11-22T10:36:00.000Z');
// Renders "247 days ago"
format.relativeTime(dateTime, {now, unit: 'day'});
}
Dates and times within messages
Dates and times can be embedded within messages by using the ICU syntax.
{
"ordered": "Ordered on {orderDate, date, medium}"
}
These formats are supported out of the box: full
, long
, medium
and short
.
If you work with translators, it can be helpful for them to use an editor that supports the ICU syntax for dates and times (e.g. the Crowdin Editor (opens in a new tab)).
You can customize the formatting by using date skeletons:
{
"ordered": "Ordered on {orderDate, date, ::yyyyMd}"
}
Note the leading ::
that is used to indicate that a skeleton should be used.
These formats from ICU are supported:
Symbol | Meaning |
---|---|
G | Era designator |
y | Year |
M | Month in year |
L | Stand-alone month in year |
d | Day in month |
E | Day of week |
e | Local day of week |
c | Stand-alone local day of week |
a | AM/PM marker |
h | Hour [1-12] |
H | Hour [0-23] |
K | Hour [0-11] |
k | Hour [1-24] |
m | Minute |
s | Second |
z | Time zone |
Custom date and time formats
To use custom formats in messages, you can provide formatters based on DateTimeFormat
options (opens in a new tab) that can be referenced by name.
{
"ordered": "Ordered on {orderDate, date, short}"
}
t(
'ordered',
{orderDate: new Date('2020-11-20T10:36:01.516Z')},
{
dateTime: {
short: {
day: 'numeric',
month: 'short',
year: 'numeric'
}
}
}
);
To reuse date and time formats for multiple components, you can configure global formats.