// Utility composable for event date handling with timezone support. // Pass `{ timeZone: event.displayTimezone }` to render in the event's TZ. export const useEventDateUtils = () => { const DEFAULT_TIMEZONE = "America/Toronto"; const formatDate = (date, options = {}) => { if (!date) return ""; const dateObj = date instanceof Date ? date : new Date(date); if (isNaN(dateObj.getTime())) return ""; const { month = "short", day = "numeric", year = "numeric", weekday, timeZone, } = options; return new Intl.DateTimeFormat("en-US", { ...(weekday && { weekday }), month, day, year, ...(timeZone && { timeZone }), }).format(dateObj); }; const formatDateRange = (startDate, endDate, compact = false, timeZone) => { if (!startDate || !endDate) return "No dates"; const start = new Date(startDate); const end = new Date(endDate); const tzOpts = timeZone ? { timeZone } : {}; const startMonth = start.toLocaleDateString("en-US", { month: "short", ...tzOpts }); const endMonth = end.toLocaleDateString("en-US", { month: "short", ...tzOpts }); const startDay = Number( start.toLocaleDateString("en-US", { day: "numeric", ...tzOpts }), ); const endDay = Number( end.toLocaleDateString("en-US", { day: "numeric", ...tzOpts }), ); const year = Number( end.toLocaleDateString("en-US", { year: "numeric", ...tzOpts }), ); const startMonthIdx = startMonth; // compared as label string const endMonthIdx = endMonth; const startYear = Number( start.toLocaleDateString("en-US", { year: "numeric", ...tzOpts }), ); if (compact) { if (startMonthIdx === endMonthIdx && startYear === year) { return `${startMonth} ${startDay}-${endDay}`; } return `${startMonth} ${startDay} - ${endMonth} ${endDay}`; } if (startMonthIdx === endMonthIdx && startYear === year) { return `${startMonth} ${startDay}-${endDay}, ${year}`; } else if (startYear === year) { return `${startMonth} ${startDay} - ${endMonth} ${endDay}, ${year}`; } else { return `${formatDate(startDate, { timeZone })} - ${formatDate(endDate, { timeZone })}`; } }; const isPastDate = (date) => { const dateObj = date instanceof Date ? date : new Date(date); return dateObj < new Date(); }; const isToday = (date, timeZone) => { const dateObj = date instanceof Date ? date : new Date(date); const today = new Date(); const opts = { year: "numeric", month: "2-digit", day: "2-digit", ...(timeZone && { timeZone }) }; return ( dateObj.toLocaleDateString("en-US", opts) === today.toLocaleDateString("en-US", opts) ); }; const formatTime = (date, includeSeconds = false, timeZone) => { const dateObj = date instanceof Date ? date : new Date(date); return new Intl.DateTimeFormat("en-US", { hour: "2-digit", minute: "2-digit", ...(includeSeconds && { second: "2-digit" }), ...(timeZone && { timeZone }), }).format(dateObj); }; return { DEFAULT_TIMEZONE, // Legacy alias for callers that hard-coded the constant. TIMEZONE: DEFAULT_TIMEZONE, formatDate, formatDateRange, isPastDate, isToday, formatTime, }; };