SkateSpots/src/lib/dateFnsI18n.ts

75 lines
2.8 KiB
TypeScript

/**
* Locale-aware date/number formatting.
*
* The app ships English + Spanish, but `date-fns` calls `formatDistanceToNow`
* with the default (English) locale and native `Date.toLocaleDateString()`
* falls back to the *runtime* locale, not the app language. This module keeps a
* single module-level locale in sync with `LanguageProvider` and re-exports all
* of `date-fns` with `formatDistanceToNow` / `formatDistance` / `format`
* overridden to apply it. Import from here instead of `date-fns` directly.
*
* `dateLocaleCode()` feeds native `toLocaleDateString/TimeString` calls so a
* Spanish user sees "5 ene" rather than "Jan 5".
*/
export * from 'date-fns';
import {
formatDistanceToNow as _formatDistanceToNow,
formatDistanceToNowStrict as _formatDistanceToNowStrict,
formatDistance as _formatDistance,
format as _format,
} from 'date-fns';
import { enUS, es as esLocale, th as thLocale, ja as jaLocale } from 'date-fns/locale';
import type { Locale } from 'date-fns';
import type { Language } from '@/contexts/language';
let activeLocale: Locale = enUS;
let activeCode = 'en-US';
/** Called by LanguageProvider (during render) so children format in-language. */
export function setDateLocale(language: Language): void {
if (language === 'es') {
activeLocale = esLocale;
activeCode = 'es-ES';
} else if (language === 'th') {
activeLocale = thLocale;
activeCode = 'th-TH';
} else if (language === 'ja') {
activeLocale = jaLocale;
activeCode = 'ja-JP';
} else {
activeLocale = enUS;
activeCode = 'en-US';
}
}
/** The active date-fns locale. */
export function dateLocale(): Locale {
return activeLocale;
}
/** BCP-47 code for native `toLocale*` / `Intl` APIs. */
export function dateLocaleCode(): string {
return activeCode;
}
type DistOptions = Parameters<typeof _formatDistanceToNow>[1];
type DistStrictOptions = Parameters<typeof _formatDistanceToNowStrict>[1];
type FormatDistanceOptions = Parameters<typeof _formatDistance>[2];
type FormatOptions = Parameters<typeof _format>[2];
export function formatDistanceToNow(date: Date | number, options?: DistOptions) {
return _formatDistanceToNow(date, { ...options, locale: options?.locale ?? activeLocale });
}
export function formatDistanceToNowStrict(date: Date | number, options?: DistStrictOptions) {
return _formatDistanceToNowStrict(date, { ...options, locale: options?.locale ?? activeLocale });
}
export function formatDistance(date: Date | number, baseDate: Date | number, options?: FormatDistanceOptions) {
return _formatDistance(date, baseDate, { ...options, locale: options?.locale ?? activeLocale });
}
export function format(date: Date | number, formatStr: string, options?: FormatOptions) {
return _format(date, formatStr, { ...options, locale: options?.locale ?? activeLocale });
}