Many date libraries support displaying relative time, such as "yesterday", "five minutes ago", "two months ago" and so on. Due to different languages, date display formats and related words are different, resulting in a very large volume of these libraries.

Now, the browser provides the built-in Intl.RelativeTimeFormat API, you can directly display the 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 will be 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 the relative time is displayed in English.

The following is an example of displaying relative time 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 the second parameter to precisely specify the behavior of the relative time instance. The configuration objects share the following attributes. indicates the style of the returned string, possible values ​​are long (default value, such as "in 1 month"), short (such as "in 1 mo."), and narrow (such as " in 1 mo."). For some languages, the narrow style and the short style are similar. -options.localeMatcher: Represents the algorithm of matching language parameters, possible values ​​are best fit (default value) and lookup. -options.numeric: indicates whether the returned string is displayed in numbers or text. The 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, the relative time is displayed in numerical form, not text form.

To change this behavior, you can 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"


The format method of the relative time instance object accepts two parameters, followed by the value and unit of the time interval. Among them, "unit" is a string, which can accept 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


The parameters of the formatToParts() method of the relative time instance object are the same as the format() method, but it returns an array to precisely control 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, which indicates the type of output value. -value: string, which indicates the content of the output. -unit: If the output content represents a value (that is, the type attribute is not literal), then there will also be a unit attribute, which represents the unit of the value.