ESNext: Relatively format time with Intl.RelativeTimeFormat

An ECMAScript Language Feature that just moved to Stage-4, and thus will be part of ES2020, is Intl.RelativeTimeFormat. It’s a way to format time in a relative manner – such as “10 minutes ago” or “in 3 quarters” – while also keeping a language into account.

const rtf_en = new Intl.RelativeTimeFormat('en'); console.log(rtf_en.format(-1, 'day')); // ~> 1 day ago console.log(rtf_en.format(30, 'seconds')); // ~> in 30 seconds
const rtf_nl = new Intl.RelativeTimeFormat('nl-BE', { localeMatcher: 'best fit', // other values: 'lookup' numeric: 'auto', // other values: 'always' style: 'short', // other values: 'long' or 'narrow' }); console.log(rtf_nl.format(-1, 'day')); // ~> gisteren console.log(rtf_nl.format(30, 'seconds')); // ~> over 30 sec.



The constructor takes two arguments: locales and options. Both are optional:

new Intl.RelativeTimeFormat([locales[, options]]);

Possible units to use while formatting are "year", "quarter", "month", "week", "day", "hour", "minute", and "second".


Constructor Arguments


The locales argument is a BCP 47 language tag which identifies the locale to use. The main parts, amongst others, of a BCP 47 language tag are language, script, and region

  • The language part is a 2/3 character long ISO 639-1 code
  • The (optional) script part is a 4 character long ISO 15924 code
  • The (optional) region part is a 2 alpha or 3 digit long ISO 3166-1 code

When more than one part is present, they are separated by a dash (-)


  • "nl": Dutch (language).
  • "nl-BE": Dutch as used in Belgium (language + region).
  • "zh-Hans-CN": Chinese written in simplified characters as used in China (language + script + region).

When locale is omitted, it will default to the language-setting of the browser/system.


The options object allows you to tweak how Intl.RelativeTimeFormat behaves. It has the following properties:

  • localeMatcher

    The locale matching algorithm to use. Possible values are "lookup" and "best fit" (default)

  • numeric

    The format of output message. Possible values are "always" (always include a number in the output, default) or "auto" (which allows output such as “in 1 day” to be rewritten in the more natural "tomorrow")

  • style

    The length of the output message, e.g. "in 1 month" vs. "in 1 mo.". Possible values are "long" (default), "short", or “narrow” (which mostly yields the same result as "short", depending on the language)


Extracting all parts with formatToParts

If you don’t want a string to be returned, you can use formatToParts() to get an object describing all parts:

const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" }); // Format relative time using the day unit. rtf.formatToParts(-1, "day"); // > [{ type: "literal", value: "yesterday"}] rtf.formatToParts(100, "day"); // > [{ type: "literal", value: "in " }, { type: "integer", value: "100", unit: "day" }, { type: "literal", value: " days" }]


JS/Browser Support

Intl.RelativeTimeFormat shipped in V8 v7.1.179 (included Chrome 71) and Firefox 65.

Polyfills are available:


Did this help you out? Like what you see?
Consider donating.

I don’t run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)