Intl.RelativeTimeFormat API

Intl.RelativeTimeFormat API

Many date libraries support displaying relative times, such as “yesterday”, “five minutes ago”, “two months ago” and so on. Due to different languages, the format of date display and related words are different, which causes the volume of these libraries to be very large.

Now, browsers provide built-in Intl.RelativeTimeFormat API, which can directly display relative time without using these libraries.

Basic usage

Intl.RelativeTimeFormat() is a constructor that accepts a language code as a parameter and returns a relative time instance object. If the parameter is omitted, the language code of the current runtime is passed in by default.

const rtf = new Intl.RelativeTimeFormat('en');

rtf.format(3.14, 'second') // "in 3.14 seconds"
rtf.format(-15, 'minute') // "15 minutes ago"
rtf.format(8, 'hour') // "in 8 hours"
rtf.format(-2, 'day') // "2 days ago"
rtf.format(3, 'week') // "in 3 weeks"
rtf.format(-5, 'month') // "5 months ago"
rtf.format(2, 'quarter') // "in 2 quarters"
rtf.format(-42, 'year') // "42 years ago"

The above code specifies that relative time is displayed in English.

Below is an example of displaying relative times in Spanish.

const rtf = new Intl.RelativeTimeFormat('es');

rtf.format(3.14, 'second') // "dentro de 3,14 segundos"
rtf.format(-15, 'minute') // "hace 15 minutos"
rtf.format(8, 'hour') // "dentro de 8 horas"
rtf.format(-2, 'day') // "hace 2 días"
rtf.format(3, 'week') // "dentro de 3 semanas"
rtf.format(-5, 'month') // "hace 5 meses"
rtf.format(2, 'quarter') // "dentro de 2 trimestres"
rtf.format(-42, 'year') // "hace 42 años"

Intl.RelativeTimeFormat() can also accept a configuration object, as a second parameter, to precisely specify the behavior of relative time instances. Configuration objects share the following properties.

  • options.style: Indicates the style of the returned string, the possible values ​​are long (default value, such as “in 1 month”), short (such as “in 1 mo.”), narrow (such as “ in 1 mo.”). For some languages, the narrow style is similar to the short style.
  • options.localeMatcher: indicates the algorithm for matching language parameters, possible values ​​are best fit (default) and lookup.
  • options.numeric: Indicates whether the returned string is displayed in numbers or text. Possible values ​​are always (default value, always text display) and auto (automatic conversion).
// The following configuration objects, all passed in are default values
const rtf = new Intl.RelativeTimeFormat('en', {
  localeMatcher: 'best fit', // other values: 'lookup'
  style: 'long', // other values: 'short' or 'narrow'
  numeric: 'always', // other values: 'auto'
});

// Now, let's try some special cases!

rtf.format(-1, 'day') // "1 day ago"
rtf.format(0, 'day') // "in 0 days"
rtf.format(1, 'day') // "in 1 day"
rtf.format(-1, 'week') // "1 week ago"
rtf.format(0, 'week') // "in 0 weeks"
rtf.format(1, 'week') // "in 1 week"

In the above code, it shows “1 day ago” instead of “yesterday”; it shows “in 0 weeks” instead of “this week”. This is because by default, relative times are displayed numerically, not textually.

To change this behavior, change the numeric property of the configuration object to auto.

const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });

rtf.format(-1, 'day') // "yesterday"
rtf.format(0, 'day') // "today"
rtf.format(1, 'day') // "tomorrow"
rtf.format(-1, 'week') // "last week"
rtf.format(0, 'week') // "this week"
rtf.format(1, 'week') // "next week"

Intl.RelativeTimeFormat.prototype.format()

The format method of a relative time instance object accepts two parameters, the value and the unit of the time interval. where “unit” is a string that accepts the following eight values.

  • year
  • quarter
  • month
  • week
  • day
  • hour
  • minute
  • second
let rtf = new Intl.RelativeTimeFormat('en');
rtf.format(-1, "day") // "yesterday"
rtf.format(2.15, "day") // "in 2.15 days

Intl.RelativeTimeFormat.prototype.formatToParts()

The formatToParts() method of a relative time instance object takes the same arguments as the format() method, but returns an array that precisely controls each part of the relative time.

const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });

rtf.format(-1, 'day')
// "yesterday"
rtf.formatToParts(-1, 'day');
// [{ type: "literal", value: "yesterday" }]

rtf.format(3, 'week');
// "in 3 weeks"
rtf.formatToParts(3, 'week');
// [
// { type: 'literal', value: 'in ' },
// { type: 'integer', value: '3', unit: 'week' },
// { type: 'literal', value: ' weeks' }
// ]

Each member of the returned array is an object with two properties.

  • type: String, indicating the type of the output value.
  • value: String, indicating the content of the output.
  • unit: If the output represents a numeric value (that is, the type attribute is not literal), then there will also be a unit attribute, which represents the unit of the value.

Reference link