type RelativeTimeOptions = { now?: Date; locale?: string; }; export function formatRelativeTime(value: string | null | undefined, options?: RelativeTimeOptions): string { if (!value) { return ''; } const date = new Date(value); if (Number.isNaN(date.getTime())) { return value; } const now = options?.now ?? new Date(); const diffSeconds = Math.round((date.getTime() - now.getTime()) / 1000); const absSeconds = Math.abs(diffSeconds); const rtf = new Intl.RelativeTimeFormat(options?.locale, { numeric: 'auto' }); if (absSeconds < 60) { return rtf.format(diffSeconds, 'second'); } const diffMinutes = Math.round(diffSeconds / 60); if (Math.abs(diffMinutes) < 60) { return rtf.format(diffMinutes, 'minute'); } const diffHours = Math.round(diffMinutes / 60); if (Math.abs(diffHours) < 24) { return rtf.format(diffHours, 'hour'); } const diffDays = Math.round(diffHours / 24); if (Math.abs(diffDays) < 7) { return rtf.format(diffDays, 'day'); } const diffWeeks = Math.round(diffDays / 7); if (Math.abs(diffWeeks) < 4) { return rtf.format(diffWeeks, 'week'); } const diffMonths = Math.round(diffDays / 30); if (Math.abs(diffMonths) < 12) { return rtf.format(diffMonths, 'month'); } const diffYears = Math.round(diffDays / 365); return rtf.format(diffYears, 'year'); }