Skip to content

Relative Time

  • The core functions, which every industry uses.

There is one relative formatter per value type. Pick the one matching your input; all share the same option shape.

Input shapeFormatterModule
ISO date "2024-03-15"formatRelativeDate@northguild/gmt
ISO time "14:30:45"formatRelativeTime@northguild/gmt
ISO datetime "2024-03-15T14:30:45"formatRelativeDateTime@northguild/gmt
Zoned "…[America/New_York]"formatRelativeZoned@northguild/gmt/zoned
Unix epoch (ms or seconds)formatRelativeUnix@northguild/gmt/unix
UTC ISO "…Z"formatRelativeUtc@northguild/gmt/utc
import { formatRelativeDate } from "@northguild/gmt";
import { formatRelativeZoned } from "@northguild/gmt/zoned";
import { formatRelativeUnix } from "@northguild/gmt/unix";
import { formatRelativeUtc } from "@northguild/gmt/utc";
const ref = "2024-03-15";
formatRelativeDate("2024-03-14", "en-US", { reference: ref }); // "yesterday"
formatRelativeDate("2024-03-12", "en-US", { reference: ref }); // "3 days ago"
formatRelativeZoned(
"2024-03-15T10:00:00-04:00[America/New_York]",
"en-US",
{ reference: "2024-03-15T12:00:00-04:00[America/New_York]" },
);
// "2 hours ago" — DST-safe via Temporal.ZonedDateTime arithmetic
formatRelativeUnix(1710507600000, "en-US", { reference: 1710511200000 });
// "1 hour ago" — default epoch unit is milliseconds
formatRelativeUtc("2024-03-15T11:00:00Z", "en-US", { reference: "2024-03-15T12:00:00Z" });
// "1 hour ago"

Style and numeric wording change the phrase, not the distance:

import { formatRelativeTime, formatRelativeDateTime } from "@northguild/gmt";
formatRelativeTime("11:30:00", "en-US", { reference: "14:30:00", style: "short" });
// "3 hr. ago"
formatRelativeDateTime("2024-03-15T15:00:00", "en-GB", {
reference: "2024-03-15T12:00:00",
style: "long",
numeric: "always",
});
// "in 3 hours"

All relative formatters accept the same option shape (besides their type-specific reference):

  • reference — anchor of the same input shape; omitted, it is now (the system clock).
  • numeric: "auto" | "always" — default "auto". "auto" produces “yesterday”/“tomorrow”; "always" forces “1 day ago”/“in 1 day”.
  • style: "long" | "short" | "narrow" — default "long".
  • largestUnit — override the auto-picked unit (e.g. "week" to force “6 weeks ago” instead of “last month”). formatRelativeDate auto-picks day through year; formatRelativeTime second through hour; formatRelativeDateTime, formatRelativeZoned, formatRelativeUnix and formatRelativeUtc second through year, with the same week, month and year thresholds as formatRelativeDate (since 1.16.0; earlier releases stopped at day). Pass largestUnit: "day" to keep a 3-year distance as “1,096 days ago”. It takes a singular or plural name, "day" or "days". Each function accepts only the units its values have: formatRelativeDate day to year, formatRelativeTime second to hour, the others second to year. Any other unit returns "".
  • roundingMethod: "floor" | "ceil" | "round" — default "round". Applies to the signed value, so it respects past vs. future. Every relative formatter accepts it, and any other value returns "".

largestUnit caps the auto-picked unit:

import { formatRelativeUtc } from "@northguild/gmt";
formatRelativeUtc("2024-03-17T14:30:45Z", "en-US", { reference: "2026-03-17T14:30:45Z" });
// "2 years ago"
formatRelativeUtc("2024-03-17T14:30:45Z", "en-US", {
reference: "2026-03-17T14:30:45Z",
largestUnit: "day",
});
// "730 days ago"

A unix epoch takes its unit through epochUnit, and reference is in the same unit:

import { formatRelativeUnix } from "@northguild/gmt";
formatRelativeUnix(1710685845000, "en-US", {
epochUnit: "milliseconds",
reference: 1805358645000,
});
// "3 years ago"

An unsupported unit or rounding method gives the sentinel, not a guess:

import { formatRelativeDate } from "@northguild/gmt";
formatRelativeDate("2024-03-12", "en-US", { reference: "2024-03-15", largestUnit: "hour" });
// "" — a date has no hours
formatRelativeDate("2024-03-12", "en-US", { reference: "2024-03-15", roundingMethod: "trunc" });
// "" — not one of floor, ceil or round

These formatters delegate to the host runtime’s Intl.RelativeTimeFormat. Output depends on the ICU and CLDR data shipped with the runtime:

  • CLDR version: locale idioms change between releases. formatRelativeDate("2023-03-15", "sv-SE", { reference: "2024-03-15" }) returns "i fjol" on ICU 77 and "förra året" on ICU 78, where CLDR changed the idiom.
  • Small ICU (a Node build without full ICU data): only English locale data is available, so other locales fall back to English.

This is a property of the runtime, not gmt. For consistent non-English output, pin the runtime version, deploy on a full-ICU Node build, or polyfill Intl.