Skip to content
Docs
Usage guide
Dates and times

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 all i18n differences in your Next.js app automatically.

💡

If you're formatting dates and times, you should set up a global time zone.

Formatting dates and times

You can format plain dates that are not part of a message with 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?

To parse dates, you can pass them to the Date constructor (opens in a new tab).

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.

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

Relative time durations can be formatted with a separate function:

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);
}

Note that values are rounded, so e.g. if 100 seconds have passed, "2 minutes ago" will be returned.

If you want to use a specific unit, you can pass options with the second argument:

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 "today"
  format.relativeTime(dateTime, { now, unit: 'day' });
}

Supplying now is necessary for the function to return consistent results. If you have configured a global value for now on the provider, you can omit the second argument:

format.relativeTime(dateTime);

useNow

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() {
  const now = useNow({
    // Update 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);
}

Dates and times within messages

Dates and times can be embedded within messages by using the ICU syntax.

en.json
{
  "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:

en.json
{
  "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:

SymbolMeaning
GEra designator
yYear
MMonth in year
LStand-alone month in year
dDay in month
EDay of week
eLocal day of week
cStand-alone local day of week
aAM/PM marker
hHour [1-12]
HHour [0-23]
KHour [0-11]
kHour [1-24]
mMinute
sSecond
zTime 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.

en.json
{
  "ordered": "Ordered on {orderDate, date, short}"
}
t(
  'orderDate',
  {date: 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.