diff --git a/packages/lib/CalendarService.ts b/packages/lib/CalendarService.ts index 5212d1b18e..25b16f37b7 100644 --- a/packages/lib/CalendarService.ts +++ b/packages/lib/CalendarService.ts @@ -47,6 +47,17 @@ const getDuration = (start: string, end: string): DurationObject => ({ minutes: dayjs(end).diff(dayjs(start), "minute"), }); +const buildUtcOffset = (minutes: number): string => { + const h = + minutes > 0 + ? "+" + (Math.floor(minutes / 60) < 10 ? "0" + Math.floor(minutes / 60) : Math.floor(minutes / 60)) + : "-" + + (Math.ceil(minutes / 60) > -10 ? "0" + Math.ceil(minutes / 60) * -1 : Math.ceil(minutes / 60) * -1); + const m = Math.abs(minutes % 60); + const offset = `${h}:${m}`; + return offset; +}; + const getAttendees = (attendees: Person[]): Attendee[] => attendees.map(({ email, name }) => ({ name, email, partstat: "NEEDS-ACTION" })); @@ -274,6 +285,24 @@ export default abstract class BaseCalendarService implements Calendar { if (vevent?.getFirstPropertyValue("transp") === "TRANSPARENT") return; const event = new ICAL.Event(vevent); + + const tzid: string | undefined = vevent?.getFirstPropertyValue("tzid"); + // In case of icalendar, when only tzid is available without vtimezone, we need to add vtimezone explicitly to take care of timezone diff + if (!vcalendar.getFirstSubcomponent("vtimezone") && tzid) { + const timezoneComp = new ICAL.Component("vtimezone"); + timezoneComp.addPropertyWithValue("tzid", tzid); + const standard = new ICAL.Component("standard"); + // get timezone offset + const tzoffsetfrom = buildUtcOffset(dayjs(event.startDate.toJSDate()).tz(tzid, true).utcOffset()); + const tzoffsetto = buildUtcOffset(dayjs(event.endDate.toJSDate()).tz(tzid, true).utcOffset()); + // set timezone offset + standard.addPropertyWithValue("tzoffsetfrom", tzoffsetfrom); + standard.addPropertyWithValue("tzoffsetto", tzoffsetto); + // provide a standard dtstart + standard.addPropertyWithValue("dtstart", "1601-01-01T00:00:00"); + timezoneComp.addSubcomponent(standard); + vcalendar.addSubcomponent(timezoneComp); + } const vtimezone = vcalendar.getFirstSubcomponent("vtimezone"); if (event.isRecurring()) {