73 lines · 2.5 KB · TypeScript
RawDownload
import { type TimestampFormat } from "@t3tools/contracts/settings"; export function getTimestampFormatOptions(  timestampFormat: TimestampFormat,  includeSeconds: boolean,): Intl.DateTimeFormatOptions {  const baseOptions: Intl.DateTimeFormatOptions = {    hour: "numeric",    minute: "2-digit",    ...(includeSeconds ? { second: "2-digit" } : {}),  };   if (timestampFormat === "locale") {    return baseOptions;  }   return {    ...baseOptions,    hour12: timestampFormat === "12-hour",  };} const timestampFormatterCache = new Map<string, Intl.DateTimeFormat>(); function getTimestampFormatter(  timestampFormat: TimestampFormat,  includeSeconds: boolean,): Intl.DateTimeFormat {  const cacheKey = `${timestampFormat}:${includeSeconds ? "seconds" : "minutes"}`;  const cachedFormatter = timestampFormatterCache.get(cacheKey);  if (cachedFormatter) {    return cachedFormatter;  }   const formatter = new Intl.DateTimeFormat(    undefined,    getTimestampFormatOptions(timestampFormat, includeSeconds),  );  timestampFormatterCache.set(cacheKey, formatter);  return formatter;} export function formatTimestamp(isoDate: string, timestampFormat: TimestampFormat): string {  return getTimestampFormatter(timestampFormat, true).format(new Date(isoDate));} export function formatShortTimestamp(isoDate: string, timestampFormat: TimestampFormat): string {  return getTimestampFormatter(timestampFormat, false).format(new Date(isoDate));} /** * Format a relative time string from an ISO date. * Returns `{ value: "20s", suffix: "ago" }` or `{ value: "just now", suffix: null }` * so callers can style the numeric portion independently. */export function formatRelativeTime(isoDate: string): { value: string; suffix: string | null } {  const diffMs = Date.now() - new Date(isoDate).getTime();  if (diffMs < 0) return { value: "just now", suffix: null };  const seconds = Math.floor(diffMs / 1000);  if (seconds < 5) return { value: "just now", suffix: null };  if (seconds < 60) return { value: `${seconds}s`, suffix: "ago" };  const minutes = Math.floor(seconds / 60);  if (minutes < 60) return { value: `${minutes}m`, suffix: "ago" };  const hours = Math.floor(minutes / 60);  if (hours < 24) return { value: `${hours}h`, suffix: "ago" };  const days = Math.floor(hours / 24);  return { value: `${days}d`, suffix: "ago" };} export function formatRelativeTimeLabel(isoDate: string) {  const relative = formatRelativeTime(isoDate);  return relative.suffix ? `${relative.value} ${relative.suffix}` : relative.value;}