// Lightweight date/time helpers — shared across server components so we // don't reinvent toLocaleString conventions per page. export function formatRelative(iso: string, now: number = Date.now()): string { const t = new Date(iso).getTime(); if (Number.isNaN(t)) return iso; const diff = t - now; const abs = Math.abs(diff); const ago = diff < 0; const units: [string, number][] = [ ["second", 1000], ["minute", 60 * 1000], ["hour", 3600 * 1000], ["day", 24 * 3600 * 1000], ["week", 7 * 24 * 3600 * 1000], ["month", 30 * 24 * 3600 * 1000], ["year", 365 * 24 * 3600 * 1000], ]; let unit = "second"; let n = Math.round(abs / 1000); for (let i = units.length - 1; i >= 0; i--) { if (abs >= units[i][1]) { unit = units[i][0]; n = Math.round(abs / units[i][1]); break; } } const suffix = n === 1 ? unit : `${unit}s`; return ago ? `${n} ${suffix} ago` : `in ${n} ${suffix}`; } export function formatDateTime(iso: string): string { const d = new Date(iso); if (Number.isNaN(d.getTime())) return iso; // YYYY-MM-DD HH:MM:SS — locale-stable, sortable, no surprises. const pad = (n: number) => String(n).padStart(2, "0"); return ( d.getUTCFullYear() + "-" + pad(d.getUTCMonth() + 1) + "-" + pad(d.getUTCDate()) + " " + pad(d.getUTCHours()) + ":" + pad(d.getUTCMinutes()) + ":" + pad(d.getUTCSeconds()) + " UTC" ); } export function truncate(s: string, max = 40): string { if (s.length <= max) return s; return s.slice(0, max - 1) + "…"; }