/* ============================================================================ LOCALE-AWARE FORMATTING ---------------------------------------------------------------------------- Thin `Intl` wrappers so a route never hard-codes a date pattern. Arabic uses ar-LY with the `latn` numbering system: the approved draft copy writes Arabic dates and figures in Western digits ("30 يونيو", "2025"), so Eastern Arabic numerals would contradict the source content. ========================================================================= */ import { INTL_LOCALE, type Locale } from "./config"; const NUMBERING_SYSTEM = "latn"; /** The BCP-47 tag (with numbering system) handed to `Intl`. */ export function intlLocale(locale: Locale): string { return `${INTL_LOCALE[locale]}-u-nu-${NUMBERING_SYSTEM}`; } function toDate(value: Date | string | number): Date | null { const date = value instanceof Date ? value : new Date(value); return Number.isNaN(date.getTime()) ? null : date; } export type DateStyle = "full" | "long" | "medium" | "short"; /** "12 March 2026" / "12 مارس 2026". Returns "" for an unparseable input. */ export function formatDate( value: Date | string | number | null | undefined, locale: Locale, options: Intl.DateTimeFormatOptions = { dateStyle: "long" }, ): string { if (value === null || value === undefined) return ""; const date = toDate(value); if (!date) return ""; return new Intl.DateTimeFormat(intlLocale(locale), options).format(date); } /** Date plus time of day, for an event card or an event detail page. */ export function formatDateTime( value: Date | string | number | null | undefined, locale: Locale, options: Intl.DateTimeFormatOptions = { dateStyle: "long", timeStyle: "short", }, ): string { return formatDate(value, locale, options); } /** "12–14 March 2026". Falls back to a single date when `end` is missing. */ export function formatDateRange( start: Date | string | number, end: Date | string | number | null | undefined, locale: Locale, options: Intl.DateTimeFormatOptions = { dateStyle: "long" }, ): string { const from = toDate(start); if (!from) return ""; const to = end === null || end === undefined ? null : toDate(end); if (!to || from.getTime() === to.getTime()) { return formatDate(from, locale, options); } return new Intl.DateTimeFormat(intlLocale(locale), options).formatRange( from, to, ); } /** The machine-readable value for `