or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

@formatjs/intl-relativetimeformat

A polyfill and implementation for the Intl.RelativeTimeFormat API that formats JavaScript dates and time values into human-readable relative time strings (e.g., '2 days ago', 'in 3 hours'). It provides comprehensive internationalization support with locale-aware formatting capabilities and supports all standard relative time units.

Package Information

  • Package Name: @formatjs/intl-relativetimeformat
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @formatjs/intl-relativetimeformat

Core Imports

import RelativeTimeFormat from "@formatjs/intl-relativetimeformat";

For CommonJS:

const RelativeTimeFormat = require("@formatjs/intl-relativetimeformat").default;

Basic Usage

import RelativeTimeFormat from "@formatjs/intl-relativetimeformat";

// Create formatter with default locale
const rtf = new RelativeTimeFormat("en", {
  style: "long", // "long" | "short" | "narrow"
  numeric: "auto" // "auto" | "always"
});

// Format relative time
console.log(rtf.format(-1, "day")); // "yesterday"
console.log(rtf.format(-2, "day")); // "2 days ago"
console.log(rtf.format(1, "hour")); // "in 1 hour"
console.log(rtf.format(3, "week")); // "in 3 weeks"

// Format to parts for custom rendering
const parts = rtf.formatToParts(-2, "day");
// [{ type: "integer", value: "2" }, { type: "literal", value: " days ago" }]

Capabilities

RelativeTimeFormat Constructor

Creates a new RelativeTimeFormat instance with locale and formatting options.

/**
 * Creates a new RelativeTimeFormat instance
 * @param locales - Locale identifier(s) or array of locale identifiers
 * @param options - Configuration options for formatting behavior
 */
constructor(
  locales?: string | string[],
  options?: Intl.RelativeTimeFormatOptions
);

interface Intl.RelativeTimeFormatOptions {
  /** The formatting style to use */
  style?: "long" | "short" | "narrow";
  /** Whether to use numeric output always or auto text when available */
  numeric?: "always" | "auto";
  /** The locale matching algorithm to use */
  localeMatcher?: "lookup" | "best fit";
  /** The numbering system to use */
  numberingSystem?: string;
}

String Formatting

Formats a relative time value into a localized string.

/**
 * Formats a relative time value into a localized string
 * @param value - The numeric value (positive for future, negative for past)
 * @param unit - The time unit for the value
 * @returns Formatted relative time string
 */
format(value: number, unit: Intl.RelativeTimeFormatUnit): string;

type Intl.RelativeTimeFormatUnit = 
  | "second" | "seconds" 
  | "minute" | "minutes"
  | "hour" | "hours"
  | "day" | "days"
  | "week" | "weeks" 
  | "month" | "months"
  | "quarter" | "quarters"
  | "year" | "years";

Usage Examples:

const rtf = new RelativeTimeFormat("en");

// Past times (negative values)
rtf.format(-1, "second"); // "1 second ago"
rtf.format(-30, "minute"); // "30 minutes ago" 
rtf.format(-2, "hour"); // "2 hours ago"
rtf.format(-1, "day"); // "1 day ago"

// Future times (positive values)
rtf.format(1, "week"); // "in 1 week"
rtf.format(6, "month"); // "in 6 months"
rtf.format(2, "year"); // "in 2 years"

// With different styles
const shortRtf = new RelativeTimeFormat("en", { style: "short" });
shortRtf.format(-2, "day"); // "2 days ago"

const narrowRtf = new RelativeTimeFormat("en", { style: "narrow" });
narrowRtf.format(1, "hour"); // "in 1 hr."

Parts Formatting

Formats a relative time value into an array of parts for custom rendering.

/**
 * Formats a relative time value into an array of parts
 * @param value - The numeric value (positive for future, negative for past)
 * @param unit - The time unit for the value
 * @returns Array of formatting parts with type and value
 */
formatToParts(
  value: number, 
  unit: Intl.RelativeTimeFormatUnit
): Intl.RelativeTimeFormatPart[];

interface Intl.RelativeTimeFormatPart {
  /** The type of this part */
  type: "literal" | "integer";
  /** The string value of this part */
  value: string;
}

Usage Examples:

const rtf = new RelativeTimeFormat("en");

// Get parts for custom styling
const parts = rtf.formatToParts(-2, "day");
// [{ type: "integer", value: "2" }, { type: "literal", value: " days ago" }]

// Render with custom HTML
const html = parts
  .map(part => 
    part.type === "integer" 
      ? `<strong>${part.value}</strong>` 
      : part.value
  )
  .join("");
// "<strong>2</strong> days ago"

// Different locales produce different parts
const germanRtf = new RelativeTimeFormat("de");
const germanParts = germanRtf.formatToParts(1, "week");
// [{ type: "literal", value: "in " }, { type: "integer", value: "1" }, { type: "literal", value: " Woche" }]

Resolved Options

Returns the resolved formatting options for the instance.

/**
 * Returns the resolved formatting options
 * @returns Object containing the resolved locale and formatting options
 */
resolvedOptions(): Intl.ResolvedRelativeTimeFormatOptions;

interface Intl.ResolvedRelativeTimeFormatOptions {
  /** The resolved locale identifier */
  locale: string;
  /** The resolved formatting style */
  style: "long" | "short" | "narrow";
  /** The resolved numeric option */
  numeric: "always" | "auto";
  /** The resolved numbering system */
  numberingSystem: string;
}

Supported Locales

Static method to determine which locales are supported from a given list.

/**
 * Returns the subset of provided locales that are supported
 * @param locales - Locale identifier(s) to check for support
 * @param options - Options for locale matching
 * @returns Array of supported locale identifiers
 */
static supportedLocalesOf(
  locales: string | string[],
  options?: Pick<Intl.RelativeTimeFormatOptions, "localeMatcher">
): string[];

Usage Examples:

// Check which locales are supported
const supported = RelativeTimeFormat.supportedLocalesOf([
  "en", "de", "fr", "xyz-invalid"
]);
// ["en", "de", "fr"] - xyz-invalid is filtered out

// Use with locale matching options
const bestFit = RelativeTimeFormat.supportedLocalesOf(
  ["en-GB", "en-US"], 
  { localeMatcher: "best fit" }
);

Locale Data Management

Static method for adding locale data to enable additional locales.

/**
 * Adds locale data to support additional locales
 * @param data - One or more locale data objects
 */
static __addLocaleData(...data: RelativeTimeLocaleData[]): void;

interface RelativeTimeLocaleData {
  /** The locale identifier */
  locale: string;
  /** The locale-specific formatting data */
  data: LocaleFieldsData;
}

interface LocaleFieldsData {
  [field: string]: FieldData;
  nu?: Array<string | null>;
}

interface FieldData {
  '0'?: string;
  '1'?: string;
  '-1'?: string;
  '2'?: string;
  '-2'?: string;
  '3'?: string;
  '-3'?: string;
  future: {[pluralRule: string]: string};
  past: {[pluralRule: string]: string};
}

Usage Examples:

import RelativeTimeFormat from "@formatjs/intl-relativetimeformat";
import localeData from "./locale-data/es.json";

// Add Spanish locale data
RelativeTimeFormat.__addLocaleData(localeData);

// Now Spanish is supported
const esRtf = new RelativeTimeFormat("es");
esRtf.format(-1, "day"); // "ayer" (yesterday in Spanish)

Polyfill Usage

The package provides multiple ways to apply the polyfill to the global Intl object.

Conditional Polyfill

Only applies if the native implementation is missing or incomplete.

import "@formatjs/intl-relativetimeformat/polyfill";

// Now Intl.RelativeTimeFormat is available globally (if it wasn't before)
const rtf = new Intl.RelativeTimeFormat("en");

Force Polyfill

Always replaces the native implementation with this polyfill.

import "@formatjs/intl-relativetimeformat/polyfill-force";

// Intl.RelativeTimeFormat now uses this polyfill implementation
const rtf = new Intl.RelativeTimeFormat("en");

Polyfill Detection

Check if polyfill is needed for a specific locale.

import { shouldPolyfill } from "@formatjs/intl-relativetimeformat/should-polyfill";

const needsPolyfill = shouldPolyfill("en-GB");
if (needsPolyfill) {
  // Apply polyfill conditionally
  await import("@formatjs/intl-relativetimeformat/polyfill");
}

Types

// Static property indicating this is a polyfill
static polyfilled: boolean; // Always true

// Available supported locales array
export const supportedLocales: string[]; // Array of 500+ locale identifiers

// Polyfill detection function
export function shouldPolyfill(locale?: string): string | undefined;

Error Handling

The implementation throws appropriate errors for invalid usage:

// TypeError: Intl.RelativeTimeFormat must be called with 'new'
const rtf = RelativeTimeFormat("en"); // Missing 'new'

// TypeError: format was called on a non-object
RelativeTimeFormat.prototype.format.call(null, 1, "day");

// TypeError: format was called on a invalid context  
const rtf = Object.create(RelativeTimeFormat.prototype);
rtf.format(1, "day"); // Not properly initialized

Browser and Node.js Compatibility

  • Node.js: Requires Node.js 12+ for full compatibility
  • Browsers: Works in all modern browsers; provides polyfill for older browsers lacking native support
  • TypeScript: Full TypeScript definitions included
  • Dependencies: Requires @formatjs/ecma402-abstract and @formatjs/intl-localematcher