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

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

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:

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' }
// ]