| const dateTimeFormatters = new Map<string, Intl.DateTimeFormat>(); |
| const compactDateTimeFormatters = new Map<string, Intl.DateTimeFormat>(); |
| const numberFormatters = new Map<string, Intl.NumberFormat>(); |
|
|
| export function formatDateTime(value: string | null | undefined, locale: string): string { |
| if (!value) { |
| return "-"; |
| } |
| const date = new Date(value); |
| if (Number.isNaN(date.getTime())) { |
| return "-"; |
| } |
| let formatter = dateTimeFormatters.get(locale); |
| if (!formatter) { |
| formatter = new Intl.DateTimeFormat(locale, { |
| dateStyle: "medium", |
| timeStyle: "short", |
| }); |
| dateTimeFormatters.set(locale, formatter); |
| } |
| return formatter.format(date); |
| } |
|
|
| export function formatCompactDateTime(value: string | null | undefined, locale: string): string { |
| if (!value) { |
| return "-"; |
| } |
| const date = new Date(value); |
| if (Number.isNaN(date.getTime())) { |
| return "-"; |
| } |
| let formatter = compactDateTimeFormatters.get(locale); |
| if (!formatter) { |
| formatter = new Intl.DateTimeFormat(locale, { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", hourCycle: "h23" }); |
| compactDateTimeFormatters.set(locale, formatter); |
| } |
| const parts = formatter.formatToParts(date); |
| return `${datePart(parts, "year")}/${datePart(parts, "month")}/${datePart(parts, "day")} ${datePart(parts, "hour")}:${datePart(parts, "minute")}:${datePart(parts, "second")}`; |
| } |
|
|
| function datePart(parts: Intl.DateTimeFormatPart[], type: Intl.DateTimeFormatPartTypes): string { |
| return parts.find((part) => part.type === type)?.value ?? "--"; |
| } |
|
|
| export function formatNumber(value: number, locale: string, maximumFractionDigits = 2): string { |
| const key = `${locale}:${maximumFractionDigits}`; |
| let formatter = numberFormatters.get(key); |
| if (!formatter) { |
| formatter = new Intl.NumberFormat(locale, { maximumFractionDigits }); |
| numberFormatters.set(key, formatter); |
| } |
| return formatter.format(value); |
| } |
|
|
| export function formatDuration(milliseconds: number): string { |
| if (milliseconds < 1000) { |
| return `${milliseconds} ms`; |
| } |
| return `${(milliseconds / 1000).toFixed(milliseconds < 10000 ? 2 : 1)} s`; |
| } |
|
|
| export function toDateTimeLocal(value: string | null | undefined): string { |
| if (!value) { |
| return ""; |
| } |
| const date = new Date(value); |
| const offset = date.getTimezoneOffset() * 60_000; |
| return new Date(date.getTime() - offset).toISOString().slice(0, 19); |
| } |
|
|