JavaScript Intl.RelativeTimeFormat Guide
The Intl.RelativeTimeFormat object in JavaScript is a
built-in internationalization API that formats language-sensitive
relative time strings, such as “yesterday,” “in 2 days,” or “3 months
ago.” This guide explains how to initialize the formatter, configure it
to produce natural-language terms instead of raw numbers, and apply its
methods across different locales and time units.
Basic Syntax and Initialization
To use Intl.RelativeTimeFormat, create an instance by
passing a locale identifier and an optional configuration object:
const rtf = new Intl.RelativeTimeFormat(locale, options);locale(string): A BCP 47 language tag (e.g.,'en','es','fr','de').options(object): Configuration properties that control the formatting output.
Formatting Relative Intervals Like “Yesterday”
By default, the formatter returns numeric expressions (e.g., “1 day
ago”). To produce idiomatic words like “yesterday” or “tomorrow,” you
must set the numeric property to 'auto'.
Configuration Options
numeric:'always'(default): Always uses numbers (e.g., “1 day ago”, “in 1 day”).'auto': Uses natural language terms where available (e.g., “yesterday”, “tomorrow”, “today”).
style:'long'(default): e.g., “yesterday”, “in 1 month”'short': e.g., “yesterday”, “in 1 mo.”'narrow': e.g., “yesterday”, “in 1m”
Code Example
// Default behavior: numeric is 'always'
const rtfDefault = new Intl.RelativeTimeFormat('en', { numeric: 'always' });
console.log(rtfDefault.format(-1, 'day')); // "1 day ago"
// Natural language behavior: numeric is 'auto'
const rtfAuto = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtfAuto.format(-1, 'day')); // "yesterday"
console.log(rtfAuto.format(0, 'day')); // "today"
console.log(rtfAuto.format(1, 'day')); // "tomorrow"
console.log(rtfAuto.format(-1, 'week')); // "last week"
console.log(rtfAuto.format(1, 'year')); // "next year"Supported Units
The format(value, unit) method accepts negative numbers
(past), zero (present), and positive numbers (future). The supported
time units are:
'year'/'years''quarter'/'quarters''month'/'months''week'/'weeks''day'/'days''hour'/'hours''minute'/'minutes''second'/'seconds'
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-2, 'day')); // "2 days ago"
console.log(rtf.format(5, 'minute')); // "in 5 minutes"Localization Support
Intl.RelativeTimeFormat automatically translates
relative strings into the specified locale without requiring third-party
libraries:
// Spanish
const rtfEs = new Intl.RelativeTimeFormat('es', { numeric: 'auto' });
console.log(rtfEs.format(-1, 'day')); // "ayer"
console.log(rtfEs.format(1, 'day')); // "mañana"
// French
const rtfFr = new Intl.RelativeTimeFormat('fr', { numeric: 'auto' });
console.log(rtfFr.format(-1, 'day')); // "hier"
console.log(rtfFr.format(1, 'day')); // "demain"
// German
const rtfDe = new Intl.RelativeTimeFormat('de', { numeric: 'auto' });
console.log(rtfDe.format(-1, 'day')); // "gestern"
console.log(rtfDe.format(1, 'day')); // "morgen"Using formatToParts()
If you need custom styling for specific parts of the output string,
use formatToParts() instead of format(). It
returns an array of objects representing the individual tokens of the
formatted relative time:
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'always' });
const parts = rtf.formatToParts(-1, 'day');
console.log(parts);
// Output:
// [
// { type: 'integer', value: '1', unit: 'day' },
// { type: 'literal', value: ' day ago' }
// ]When using { numeric: 'auto' } with terms like
“yesterday”, the entire phrase is returned as a single literal part:
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
const parts = rtf.formatToParts(-1, 'day');
console.log(parts);
// Output:
// [
// { type: 'literal', value: 'yesterday' }
// ]