75 lines
2.8 KiB
TypeScript
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 });
|
|
}
|