I am working on an application which generates .ICS calendar files for events. When I test opening a generated event, the timezone data is ignored by outlook, and assumed (incorrectly) to be my computer's local timezone - hence the times are incorrect on the calendar if the event is saved.
For example, this test event is set to US Mountain Time (UTC-6), 10:00 AM - 11:00 AM. When I open it via Outlook on my computer (which is US Eastern Time (UTC-4)), it is showing the event occurring at 10:00 AM - 11:00 AM Eastern Time, which is incorrect.
Here is the content of the ICS file. This passes the Validator at https://icalendar.org/validator.html which is based on the RFC 5545 specification.
BEGIN:VCALENDAR
METHOD:PUBLISH
PRODID:-//github.com/rianjs/ical.net//NONSGML ical.net 4.0//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Denver
X-LIC-LOCATION:America/Denver
BEGIN:STANDARD
DTSTART:20201101T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
TZNAME:MST
TZOFFSETFROM:-0600
TZOFFSETTO:-0700
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20210314T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
TZNAME:MDT
TZOFFSETFROM:-0700
TZOFFSETTO:-0600
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DESCRIPTION:
DTEND:20220415T110000
DTSTAMP:20220414T190522Z
DTSTART:20220415T100000
LOCATION:
PRIORITY:5
SEQUENCE:0
SUMMARY:Event Test - Mountain Time
UID:d36af76c-1914-43a2-bb04-84e714a157c3
X-ALT-DESC;FMTTYPE=text/html:
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:Reminder
TRIGGER:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR
If, in Outlook, I manually adjust the timezone on the calendar item:
and Save it, it appears in the correct place on my (Eastern Time) calendar (shifted by 2 hours):
If I then "Save As..." this edited calendar entry as an ICS file and open it, this is its contents:
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VTIMEZONE
TZID:Mountain Standard Time
BEGIN:STANDARD
DTSTART:16011104T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
TZOFFSETFROM:-0600
TZOFFSETTO:-0700
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010311T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
TZOFFSETFROM:-0700
TZOFFSETTO:-0600
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
CLASS:PUBLIC
CREATED:20220414T191551Z
DTEND;TZID="Mountain Standard Time":20220415T110000
DTSTAMP:20220414T190522Z
DTSTART;TZID="Mountain Standard Time":20220415T100000
LAST-MODIFIED:20220414T191551Z
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=en-us:Event Test - Mountain Time
TRANSP:OPAQUE
UID:d36af76c-1914-43a2-bb04-84e714a157c3
X-ALT-DESC;FMTTYPE=text/html:
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
BEGIN:VALARM
TRIGGER:-PT15M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR
The main differences I notice are that the timezone data stored is not the IANA standard, but rather the Microsoft "TimeZoneInfo" name ("Mountain Standard Time" rather than "America/Denver").
Additionally, this is flagged when testing it via the Validator tool:
Why doesn't Outlook recognize IANA timezones? Why doesn't Outook follow the ICS standard?