/** * Toolkit - Date Formatting * * Utilities for formatting dates and times. */ export type DateFormatStyle = "short" | "medium" | "long" | "full"; export interface DateFormatOptions { locale?: string; dateStyle?: DateFormatStyle; timeStyle?: DateFormatStyle; includeTime?: boolean; timezone?: string; } /** * Format an ISO date string for display */ export function formatDate( isoString: string, options: DateFormatOptions = {} ): string { const { locale = "en-US", dateStyle = "medium", timeStyle = "short", includeTime = false, timezone, } = options; try { const date = new Date(isoString); if (isNaN(date.getTime())) { return isoString; // Return original if invalid } const formatOptions: Intl.DateTimeFormatOptions = { dateStyle, ...(includeTime && { timeStyle }), ...(timezone && { timeZone: timezone }), }; return new Intl.DateTimeFormat(locale, formatOptions).format(date); } catch { return isoString; // Return original on error } } /** * Format a date relative to now (e.g., "2 days ago", "in 3 hours") */ export function formatRelativeDate( isoString: string, options: { locale?: string } = {} ): string { const { locale = "en-US" } = options; try { const date = new Date(isoString); const now = new Date(); const diffMs = date.getTime() - now.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); // Use Intl.RelativeTimeFormat for proper localization const formatter = new Intl.RelativeTimeFormat(locale, { numeric: "auto" }); if (Math.abs(diffDays) > 0) { return formatter.format(diffDays, "day"); } else if (Math.abs(diffHours) > 0) { return formatter.format(diffHours, "hour"); } else if (Math.abs(diffMinutes) > 0) { return formatter.format(diffMinutes, "minute"); } else { return formatter.format(diffSeconds, "second"); } } catch { return isoString; } } /** * Check if a date string is valid */ export function isValidDate(dateString: string): boolean { const date = new Date(dateString); return !isNaN(date.getTime()); }