50 lines
2.0 KiB
TypeScript
50 lines
2.0 KiB
TypeScript
function formatTime(seconds: number): string {
|
|
const h = Math.floor(seconds / 3600);
|
|
const m = Math.floor((seconds % 3600) / 60);
|
|
const s = Math.floor(seconds % 60);
|
|
const pad = (n: number) => n.toString().padStart(2, '0');
|
|
if (h > 0) return `${h}:${pad(m)}:${pad(s)}`;
|
|
return `${m}:${pad(s)}`;
|
|
}
|
|
|
|
// Parses a UTC date string, appending Z if no timezone offset is present so
|
|
// the browser always interprets the value as UTC rather than local time.
|
|
function stringToDate(dateString: string): Date {
|
|
const normalized = dateString.replace(/(\.\d{3})\d+/, "$1");
|
|
const withTz = /[Zz]$|[+-]\d{2}:\d{2}$|[+-]\d{4}$/.test(normalized) ? normalized : `${normalized}Z`;
|
|
const date = new Date(withTz);
|
|
if (isNaN(date.getTime())) throw new Error("Invalid date string");
|
|
return date;
|
|
}
|
|
|
|
function formatLocalDate(dateString: string, options?: Intl.DateTimeFormatOptions): string {
|
|
return stringToDate(dateString).toLocaleDateString(undefined, options ?? { year: "numeric", month: "long", day: "numeric" });
|
|
}
|
|
|
|
// Clock time only, no date — markers within a stream are all from the same day,
|
|
// so the date would just be noise beside them.
|
|
function formatLocalTime(dateString: string): string {
|
|
return stringToDate(dateString).toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
}
|
|
|
|
function dateToTimeAgo(date: Date): string {
|
|
const secondsAgo = Math.floor((Date.now() - date.getTime()) / 1000);
|
|
const units: [number, string][] = [
|
|
[31536000, 'year'],
|
|
[2592000, 'month'],
|
|
[86400, 'day'],
|
|
[3600, 'hour'],
|
|
[60, 'minute'],
|
|
];
|
|
for (const [threshold, unit] of units) {
|
|
if (secondsAgo >= threshold) {
|
|
const count = Math.floor(secondsAgo / threshold);
|
|
return `${count} ${unit}${count !== 1 ? 's' : ''} ago`;
|
|
}
|
|
}
|
|
const s = Math.max(0, secondsAgo);
|
|
return `${s} second${s !== 1 ? 's' : ''} ago`;
|
|
}
|
|
|
|
export { formatTime, stringToDate, dateToTimeAgo, formatLocalDate, formatLocalTime };
|