export function fmtCurrency(value?: number | null, decimals = 2): string { if (value === null || value === undefined || Number.isNaN(value)) return "-"; return `$${value.toLocaleString(undefined, { maximumFractionDigits: decimals, minimumFractionDigits: decimals })}`; } export function fmtNumber(value?: number | null, decimals = 2): string { if (value === null || value === undefined || Number.isNaN(value)) return "-"; return value.toLocaleString(undefined, { maximumFractionDigits: decimals, minimumFractionDigits: decimals }); } export function fmtLarge(value?: number | null): string { if (value === null || value === undefined || Number.isNaN(value)) return "-"; const abs = Math.abs(value); const sign = value < 0 ? "-" : ""; if (abs >= 1e12) return `${sign}$${(abs / 1e12).toFixed(2)}T`; if (abs >= 1e9) return `${sign}$${(abs / 1e9).toFixed(2)}B`; if (abs >= 1e6) return `${sign}$${(abs / 1e6).toFixed(1)}M`; return `${sign}$${abs.toLocaleString(undefined, { maximumFractionDigits: 0 })}`; } export function fmtPct(value?: number | null, decimals = 2, signed = false): string { if (value === null || value === undefined || Number.isNaN(value)) return "-"; const pct = value * 100; const sign = signed && pct > 0 ? "+" : ""; return `${sign}${pct.toFixed(decimals)}%`; } export function deltaClass(value?: number | null): string { if (value === null || value === undefined) return "neutral"; return value >= 0 ? "positive" : "negative"; } export function formatNewsTimestamp(iso: string): { display: string; iso: string } { const date = new Date(iso); const now = new Date(); const tz: Intl.DateTimeFormatOptions = { timeZone: "America/Los_Angeles" }; const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / 60_000); const diffHours = Math.floor(diffMs / 3_600_000); if (diffMins < 1) { return { display: "Just now", iso }; } if (diffMins < 60) { return { display: `${diffMins}m ago`, iso }; } if (diffHours < 24) { return { display: `${diffHours}h ago`, iso }; } const inTz = (options: Intl.DateTimeFormatOptions) => date.toLocaleString("en-US", { ...options, ...tz }); if (diffHours < 48) { const time = inTz({ hour: "numeric", minute: "2-digit" }); return { display: `Yesterday ${time}`, iso }; } const yearNow = Number(now.toLocaleString("en-US", { year: "numeric", ...tz })); const yearDate = Number(inTz({ year: "numeric" })); if (yearDate === yearNow) { return { display: inTz({ month: "short", day: "numeric" }), iso }; } return { display: inTz({ month: "short", day: "numeric", year: "numeric" }), iso }; }