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 | 169x 169x 169x 169x 169x 169x 169x 169x 169x 3x 166x 3x 163x 163x 163x 163x 163x 163x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x | /**
* 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);
Iif (diffSeconds < 60) {
return "just now";
}
if (diffMinutes < 60) {
return `${diffMinutes}m ago`;
}
if (diffHours < 24) {
return `${diffHours}h ago`;
}
Iif (diffDays === 1) {
return "yesterday";
}
Iif (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);
Iif (Number.isNaN(date.getTime())) {
return "\u2014";
}
const now = new Date();
const diffMs = date.getTime() - now.getTime();
Iif (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);
Iif (diffSeconds < 60) {
return `in ${diffSeconds}s`;
}
if (diffMinutes < 60) {
return `in ${diffMinutes}m`;
}
Iif (diffHours < 24) {
return `in ${diffHours}h`;
}
Iif (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()}`;
}
|