// Helpers de fecha con timezone MX. Respeta DST automáticamente // leyendo el offset real vigente para la fecha dada. const MX_TZ = 'America/Tijuana'; function tzOffset(date: Date, tz: string): string { const parts = new Intl.DateTimeFormat('en', { timeZone: tz, timeZoneName: 'longOffset', }).formatToParts(date); const s = parts.find((p) => p.type === 'timeZoneName')?.value ?? 'GMT+00:00'; const m = s.match(/GMT([+-]\d{2}:\d{2})/); return m?.[1] ?? '+00:00'; } function hourMX(now: Date = new Date()): number { const parts = new Intl.DateTimeFormat('en-GB', { timeZone: MX_TZ, hour: '2-digit', hour12: false, }).formatToParts(now); const h = parseInt(parts.find((p) => p.type === 'hour')?.value ?? '0', 10); return h % 24; // "24" en algunos runtimes al filo de medianoche. } export function saludoHora( now: Date = new Date() ): 'Buenos días' | 'Buenas tardes' | 'Buenas noches' { const h = hourMX(now); if (h >= 5 && h < 12) return 'Buenos días'; if (h >= 12 && h < 19) return 'Buenas tardes'; return 'Buenas noches'; } // "Hoy a las 15:32" / "Ayer a las 10:00" / "Hace 3 días" / fecha absoluta. export function fmtFechaRelativa(input: string | Date, now: Date = new Date()): string { const d = typeof input === 'string' ? new Date(input) : input; const hoy = todayMX(now); const suDia = todayMX(d); const diffDays = Math.round((hoy.startUTC.getTime() - suDia.startUTC.getTime()) / 86400000); const hora = new Intl.DateTimeFormat('es-MX', { timeZone: MX_TZ, hour: '2-digit', minute: '2-digit', hour12: false, }).format(d); if (diffDays === 0) return `Hoy a las ${hora}`; if (diffDays === 1) return `Ayer a las ${hora}`; if (diffDays > 1 && diffDays < 7) return `Hace ${diffDays} días`; return new Intl.DateTimeFormat('es-MX', { dateStyle: 'medium', timeZone: MX_TZ }).format(d); } export function todayMX(now: Date = new Date()): { label: string; startUTC: Date; endUTC: Date; isoDate: string; } { const isoDate = new Intl.DateTimeFormat('en-CA', { timeZone: MX_TZ, year: 'numeric', month: '2-digit', day: '2-digit', }).format(now); // YYYY-MM-DD const offset = tzOffset(now, MX_TZ); const startUTC = new Date(`${isoDate}T00:00:00${offset}`); const endUTC = new Date(startUTC.getTime() + 24 * 60 * 60 * 1000); const label = new Intl.DateTimeFormat('es-MX', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric', timeZone: MX_TZ, }).format(now); return { label, startUTC, endUTC, isoDate }; }