import { formatInTimeZone, toZonedTime } from 'date-fns-tz'; import { isSameDay as isSameDayDateFns } from 'date-fns'; /** * Formats a UTC Date into a string for a specific timezone using date-fns patterns. * Patterns: 'HH:mm' for 24h time, 'EEE' for short weekday, etc. */ export function formatZoned(date: Date, timeZone: string, pattern: string): string { return formatInTimeZone(date, timeZone, pattern); } /** * Checks if two dates are the same day in a specific timezone. * Important for comparing weather forecast days against a selected date. */ export function isSameDayInZone(date1: Date, date2: Date, timeZone: string): boolean { const z1 = toZonedTime(date1, timeZone); const z2 = toZonedTime(date2, timeZone); return isSameDayDateFns(z1, z2); } /** * Gets the numeric hour (0-23) for a date in a specific timezone. */ export function getZonedHour(date: Date, timeZone: string): number { return parseInt(formatInTimeZone(date, timeZone, 'H'), 10); } /** * Returns a relative label like "Today", "Tomorrow", "Yesterday", * or a formatted date string, all relative to the target timezone. */ export function getRelativeDayLabel(date: Date, timeZone: string): string { const now = new Date(); const zonedDate = toZonedTime(date, timeZone); const zonedNow = toZonedTime(now, timeZone); if (isSameDayDateFns(zonedDate, zonedNow)) return 'Today'; const tomorrow = new Date(zonedNow); tomorrow.setDate(tomorrow.getDate() + 1); if (isSameDayDateFns(zonedDate, tomorrow)) return 'Tomorrow'; const yesterday = new Date(zonedNow); yesterday.setDate(yesterday.getDate() - 1); if (isSameDayDateFns(zonedDate, yesterday)) return 'Yesterday'; return formatInTimeZone(date, timeZone, 'EEE d MMM'); } /** * Formats a UTC offset in seconds to a string like "UTC+1" or "UTC-05:00" */ export function formatUtcOffset(offsetSeconds: number): string { const sign = offsetSeconds >= 0 ? '+' : '-'; const abs = Math.abs(offsetSeconds); const hours = Math.floor(abs / 3600); const minutes = Math.floor((abs % 3600) / 60); const pad = (n: number) => n.toString().padStart(2, '0'); return minutes === 0 ? `UTC${sign}${hours}` : `UTC${sign}${hours}:${pad(minutes)}`; }