Skip to content

Formatting Relative Time

  • The core functions, which every industry uses.

formatRelativeDate, formatRelativeTime, and formatRelativeDateTime produce human-readable descriptions like “3 days ago” or “in 2 hours”. They require both a value and a reference point.

HIGH

Forgetting reference where the output must be deterministic

Without a reference, formatRelativeDate and friends measure from now: the system clock and, for plain values, the system time zone. The same call returns a different string tomorrow. Pass reference wherever the output is tested, cached or rendered on a server. It goes in the options object; the second argument is the locale.

Wrong

formatRelativeDate("2024-03-15", "en-US"); // measured from today — changes from day to day

Right

import { formatRelativeDate } from "@northguild/gmt";
formatRelativeDate("2024-03-15", "en-US", { reference: "2024-03-20" }); // "5 days ago"
HIGH

Mismatched input shape between value and reference

A plain date and a zoned datetime are different shapes. Passing a plain date as the value and a zoned string as the reference (or vice versa) returns an empty string.

Wrong

formatRelativeDate("2024-03-15", "en-US", { reference: "2024-03-20T10:00:00-04:00[America/New_York]" });
// "" — plain value, zoned reference

Right

import { formatRelativeDate } from "@northguild/gmt";
formatRelativeDate("2024-03-15", "en-US", { reference: "2024-03-20" }); // "5 days ago" — both plain
HIGH

Hand-rolling diff math with Date

Computing '3 days ago' by dividing a millisecond difference by 86400000 assumes every day is 24 hours, and new Date(target) reads a date-only string as UTC midnight, so the count shifts with the time of day, the host time zone and DST changes. GMT's formatRelative functions count calendar days.

Wrong

const diff = Math.floor((Date.now() - new Date(target).getTime()) / 86400000);
// "3 days" — off by one depending on the hour, the host zone, or a DST change in between

Right

import { formatRelativeDate } from "@northguild/gmt";
formatRelativeDate("2024-03-08", "en-US", { reference: "2024-03-11" }); // "3 days ago" — calendar days, across the 2024-03-10 DST change
MEDIUM

Picking the wrong formatter for a Unix value

formatRelativeUnix is the formatter for Unix timestamps. Passing a Unix value to formatRelativeDate or formatRelativeDateTime returns an empty string because the input shape does not match.

Wrong

import { formatRelativeDate } from "@northguild/gmt";
formatRelativeDate(1710504645000, "en-US"); // "" — an epoch number is not a plain date

Right

import { formatRelativeUnix } from "@northguild/gmt/unix";
formatRelativeUnix(1710504645000, "en-US", { reference: 1710504645000 }); // "now" — milliseconds by default