Formatting Date and Time
GMT’s format functions return locale-sensitive strings. They differ from
Intl.DateTimeFormat in scope, locale handling, and sentinel behavior.
Mistakes
Section titled “Mistakes”Using Intl.DateTimeFormat directly
Intl.DateTimeFormat does not cover GMT's extended format set (Rfc2822, HTTP, SQL, Rfc3339, relative), and its `formatToParts` output order varies by locale. GMT's format functions are consistent across locales and formats.
Wrong
const f = new Intl.DateTimeFormat("en-US", { dateStyle: "full" });
f.format(new Date("2024-03-15")); // "Friday, March 15, 2024" — locale-dependent orderRight
import { formatDate } from "@northguild/gmt";
formatDate("2024-03-15"); // "Friday, March 15, 2024" — locale-aware, consistent APINot handling empty string on invalid input
GMT's format functions return an empty string for invalid input. Treating that as a blank format result hides bugs in the input pipeline.
Wrong
const out = formatDate(badInput);
// if badInput is "", out is also "" — indistinguishable from a formatting bugRight
import { formatDate } from "@northguild/gmt";
const out = formatDate(input);
if (out === "") {
// input was invalid — fix upstream
}Assuming getLocale* throws or returns English for an invalid locale
getLocaleMonthNames, getLocaleEraNames, and friends return empty arrays for an unknown locale. They do not throw, and they do not fall back to English.
Wrong
const months = getLocaleMonthNames("xx-XX"); // [] — not English, not an errorRight
import { getLocaleMonthNames } from "@northguild/gmt";
const months = getLocaleMonthNames("en-US"); // known locale
// always validate or default the locale before callingLooking for a token-pattern formatter (there isn't one, deliberately)
GMT deliberately omits a `format(pattern, value)` function. Token-pattern formatters either silently ignore unknown tokens or produce garbled output on bad input. GMT's dedicated format functions are safer.
Wrong
// no equivalent of format("{yyyy}-{MM}-{dd}", date)Right
import { formatDate } from "@northguild/gmt";
formatDate("2024-03-15"); // "Friday, March 15, 2024" — dedicated function, no tokensReassembling formatToParts output in a fixed order
`Intl.DateTimeFormat.formatToParts()` returns parts in locale-specific order. Concatenating them in a hardcoded sequence (e.g. month before day) produces wrong output for `ja-JP`, `zh-CN`, and others.
Wrong
const parts = new Intl.DateTimeFormat("ja-JP").formatToParts(new Date());
// parts[0] is the era, parts[1] is the year — hardcoding order breaks other localesRight
import { formatDate } from "@northguild/gmt";
formatDate("2024-03-15"); // locale-correct order, no manual assemblyConfusing formatCalendar with formatRelativeDateTime
formatCalendar converts a date to a non-Gregorian calendar string (e.g. Japanese, Hebrew). formatRelativeDateTime produces '3 days ago' / 'in 2 hours'. They have completely different output shapes.
Wrong
const out = formatCalendar("2024-03-15", "japanese"); // "令和6年3月15日"
// used where a relative description was wantedRight
import { formatRelativeDate } from "@northguild/gmt";
formatRelativeDate("2024-03-15"); // "today" — relative description