Skip to content
Source
Sign inSign up

time.ts

32 lines1.2 KB

1export function relativeTime(input: string, nowMs: number = Date.now()): string {
2 const timestamp = Date.parse(input);
3 if (Number.isNaN(timestamp)) {
4 return "<1m";
5 }
6​
7 const deltaSeconds = Math.max(0, Math.floor((nowMs - timestamp) / 1000));
8 if (deltaSeconds < 60) return "<1m";
9​
10 const deltaMinutes = Math.floor(deltaSeconds / 60);
11 if (deltaMinutes < 60) return `${deltaMinutes}m`;
12​
13 const deltaHours = Math.floor(deltaMinutes / 60);
14 if (deltaHours < 24) return `${deltaHours}h`;
15​
16 const deltaDays = Math.floor(deltaHours / 24);
17 return `${deltaDays}d`;
19​
20/** Milliseconds until the relative-time label next changes. */
21export function msUntilRelativeTimeChange(
22 input: string,
23 nowMs: number = Date.now(),
24): number | null {
25 const timestamp = Date.parse(input);
26 if (Number.isNaN(timestamp)) return null;
27 const elapsedMs = Math.max(0, nowMs - timestamp);
28 const unitMs = elapsedMs < 3_600_000 ? 60_000 : elapsedMs < 86_400_000 ? 3_600_000 : 86_400_000;
29 const nextChangeMs = timestamp + (Math.floor(elapsedMs / unitMs) + 1) * unitMs;
30 // Far-future timestamps must not overflow setTimeout's signed 32-bit delay.
31 return Math.min(nextChangeMs - nowMs, 86_400_000);