38 lines
1.0 KiB
TypeScript
38 lines
1.0 KiB
TypeScript
// app/utils/datetime.ts
|
|
export function formatCrmTimestamp(
|
|
input: string | null | undefined,
|
|
opts?: { locale?: string; timeZone?: string; includeSeconds?: boolean }
|
|
): string {
|
|
if (!input) return 'N/A';
|
|
|
|
// Accept: 2025-06-30 10:04:58.387651 (also with 'T', with/without fraction)
|
|
const m = String(input).trim().match(
|
|
/^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,6}))?$/
|
|
);
|
|
if (!m) return input; // fallback: show as-is
|
|
|
|
const [, y, mo, d, hh, mm, ss, frac = ''] = m;
|
|
const ms = Number((frac + '000').slice(0, 3)); // micro→millis
|
|
|
|
const dt = new Date(
|
|
Number(y),
|
|
Number(mo) - 1,
|
|
Number(d),
|
|
Number(hh),
|
|
Number(mm),
|
|
Number(ss),
|
|
ms
|
|
);
|
|
|
|
const locale = opts?.locale ?? 'en-MY';
|
|
const timeZone = opts?.timeZone ?? 'Asia/Kuala_Lumpur';
|
|
const timeStyle = opts?.includeSeconds ? 'medium' : 'short';
|
|
|
|
return new Intl.DateTimeFormat(locale, {
|
|
dateStyle: 'medium',
|
|
timeStyle, // 'short'=no seconds, 'medium'=with seconds
|
|
timeZone,
|
|
hour12: true,
|
|
}).format(dt);
|
|
}
|