this repo has no description

Get calendar-level timezone fix

+20 -27
+20 -27
utils/calendarUtils.ts
··· 5 5 import parseISO from "https://deno.land/x/date_fns@v2.22.1/parseISO/index.js"; 6 6 import startOfDay from "https://deno.land/x/date_fns@v2.22.1/startOfDay/index.ts"; 7 7 import endOfDay from "https://deno.land/x/date_fns@v2.22.1/endOfDay/index.ts"; 8 - import { fromZonedTime } from "npm:date-fns-tz"; 9 8 10 9 export interface Event { 11 10 start: Date; ··· 47 46 } 48 47 49 48 const icsData = await response.text(); 49 + 50 + // Extract calendar-level timezone if present 51 + let calendarTimezone: string | null = null; 52 + const tzMatch = icsData.match(/X-WR-TIMEZONE:(.*?)(?:\r?\n)/); 53 + if (tzMatch && tzMatch[1]) { 54 + calendarTimezone = tzMatch[1].trim(); 55 + } 56 + 50 57 const events = ical.parseICS(icsData); 51 58 52 59 const parsedEvents = parseICalEvents(events).sort((a, b) => 53 60 a.start.getTime() - b.start.getTime() 54 61 ); 55 62 63 + // Apply calendar-level timezone to events that don't have their own timezone 64 + if (calendarTimezone) { 65 + parsedEvents.forEach((event) => { 66 + if (!event.timezone) event.timezone = calendarTimezone; 67 + }); 68 + } 69 + 56 70 return parsedEvents; 57 71 } 58 72 59 73 // deno-lint-ignore no-explicit-any 60 74 function parseICalEvents(icalEvents: Record<string, any>): Event[] { 61 - // Extract calendar-level timezone if available 62 - const calendarTz = 63 - Object.values(icalEvents).find((item) => item.type === "VCALENDAR") 64 - ?.["x-wr-timezone"] || "UTC"; 65 - 66 75 return Object.values(icalEvents) 67 76 .filter((event) => event.type === "VEVENT") 68 77 .map((event) => { 69 - // Use event-specific timezone if available, otherwise fallback to calendar timezone 70 - const eventTz = event.startZone || calendarTz; 71 - 72 - // Convert dates to UTC for internal comparisons 73 - const start = normalizeDate(event.start, eventTz); 74 - const end = normalizeDate(event.end, eventTz); 78 + // Extract timezone information if available 79 + const timezone = event.start?.tz ? event.start.tz.replace(/^\//, '') : null; 75 80 76 81 return { 77 - start, 78 - end, 82 + start: event.start, 83 + end: event.end, 79 84 location: event.location || "", 80 85 summary: event.summary || "", 81 86 description: event.description || "", 82 - timezone: eventTz, 87 + timezone: timezone, 83 88 }; 84 89 }); 85 - } 86 - 87 - function normalizeDate(date: Date, timezone: string): Date { 88 - if (!date) return date; 89 - 90 - try { 91 - // Convert the date to UTC while respecting the original timezone 92 - return fromZonedTime(date, timezone); 93 - } catch (e) { 94 - console.warn(`Failed to parse timezone ${timezone}:`, e); 95 - return date; 96 - } 97 90 } 98 91 99 92 export function filterEvents(