36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
export function relativeTime(iso: string): string {
|
|
const then = new Date(iso).getTime();
|
|
const diff = Date.now() - then;
|
|
const abs = Math.abs(diff);
|
|
const mins = Math.round(abs / 60000);
|
|
const suffix = diff >= 0 ? "ago" : "from now";
|
|
if (abs < 60000) return "just now";
|
|
if (mins < 60) return `${mins}m ${suffix}`;
|
|
const hours = Math.round(mins / 60);
|
|
if (hours < 24) return `${hours}h ${suffix}`;
|
|
const days = Math.round(hours / 24);
|
|
if (days < 30) return `${days}d ${suffix}`;
|
|
return new Date(iso).toLocaleDateString();
|
|
}
|
|
|
|
export function formatDateTime(iso: string): string {
|
|
return new Date(iso).toLocaleString(undefined, {
|
|
year: "numeric",
|
|
month: "short",
|
|
day: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
timeZoneName: "short",
|
|
});
|
|
}
|
|
|
|
/** Returns a human "expires in Xm" string, or "expired" if past. */
|
|
export function expiresIn(iso: string): { text: string; expired: boolean; urgent: boolean } {
|
|
const diff = new Date(iso).getTime() - Date.now();
|
|
if (diff <= 0) return { text: "expired", expired: true, urgent: false };
|
|
const mins = Math.floor(diff / 60000);
|
|
if (mins < 60) return { text: `expires in ${mins}m`, expired: false, urgent: mins < 10 };
|
|
const hours = Math.floor(mins / 60);
|
|
return { text: `expires in ${hours}h ${mins % 60}m`, expired: false, urgent: false };
|
|
}
|