/** * Format a number as a price string with 2 decimal places and thousands separators. * e.g. 1234.5 → "1,234.50" */ export function formatPrice(n: number): string { return n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2, }); } /** * Format a number as a percentage string with 2 decimal places. * e.g. 12.345 → "12.35%" */ export function formatPercent(n: number): string { return `${n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2, })}%`; } /** * Format a large number with K/M/B suffix. * Values >= 1_000_000_000 → "1.23B" * Values >= 1_000_000 → "456.7M" * Values >= 1_000 → "12.3K" * Values < 1_000 → plain number, no suffix */ export function formatLargeNumber(n: number): string { const abs = Math.abs(n); const sign = n < 0 ? '-' : ''; if (abs >= 1_000_000_000) { return `${sign}${(abs / 1_000_000_000).toFixed(2).replace(/\.?0+$/, '')}B`; } if (abs >= 1_000_000) { return `${sign}${(abs / 1_000_000).toFixed(1).replace(/\.?0+$/, '')}M`; } if (abs >= 1_000) { return `${sign}${(abs / 1_000).toFixed(1).replace(/\.?0+$/, '')}K`; } return n.toString(); } /** * Format an ISO date string as a short date. * e.g. "2025-01-15T14:30:00Z" → "Jan 15, 2025" */ export function formatDate(d: string): string { const date = new Date(d); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', }); } /** * Format an ISO date string as a date with time. * e.g. "2025-01-15T14:30:00Z" → "Jan 15, 2025 2:30 PM" */ export function formatDateTime(d: string): string { const date = new Date(d); return `${date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', })} ${date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true, })}`; }