Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | /** * Formats an ISO timestamp string as a human-readable relative time. * * Examples: * "just now" (< 1 minute ago) * "5m ago" (< 1 hour ago) * "2h ago" (< 24 hours ago) * "yesterday" (1–2 days ago) * "3 days ago" (2–7 days ago) * "Feb 27" (> 7 days ago, same year) * "Feb 27 2025" (different year) */ export function formatRelativeTime(isoString: string): string { const date = new Date(isoString); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffSeconds = Math.floor(diffMs / 1000); const diffMinutes = Math.floor(diffSeconds / 60); const diffHours = Math.floor(diffMinutes / 60); const diffDays = Math.floor(diffHours / 24); if (diffSeconds < 60) { return "just now"; } if (diffMinutes < 60) { return `${diffMinutes}m ago`; } if (diffHours < 24) { return `${diffHours}h ago`; } if (diffDays === 1) { return "yesterday"; } if (diffDays < 7) { return `${diffDays} days ago`; } // Older than a week — show a short date const sameYear = date.getFullYear() === now.getFullYear(); const month = date.toLocaleString("en-US", { month: "short" }); const day = date.getDate(); return sameYear ? `${month} ${day}` : `${month} ${day} ${date.getFullYear()}`; } /** * Formats an ISO timestamp string as a human-readable countdown to a future event. * * Examples: * "in 45s" (< 1 minute away) * "in 5m" (< 1 hour away) * "in 2h" (< 24 hours away) * "in 3 days" (< 7 days away) * "Feb 27" (> 7 days away, same year) * * Returns "overdue" if the timestamp is in the past. */ export function formatCountdown(isoString: string): string { const date = new Date(isoString); if (Number.isNaN(date.getTime())) { return "\u2014"; } const now = new Date(); const diffMs = date.getTime() - now.getTime(); if (diffMs <= 0) { return "overdue"; } const diffSeconds = Math.floor(diffMs / 1000); const diffMinutes = Math.floor(diffSeconds / 60); const diffHours = Math.floor(diffMinutes / 60); const diffDays = Math.floor(diffHours / 24); if (diffSeconds < 60) { return `in ${diffSeconds}s`; } if (diffMinutes < 60) { return `in ${diffMinutes}m`; } if (diffHours < 24) { return `in ${diffHours}h`; } if (diffDays < 7) { return `in ${diffDays} day${diffDays === 1 ? "" : "s"}`; } // Further out — show a short date const sameYear = date.getFullYear() === now.getFullYear(); const month = date.toLocaleString("en-US", { month: "short" }); const day = date.getDate(); return sameYear ? `${month} ${day}` : `${month} ${day} ${date.getFullYear()}`; } |