bitfireAT/ical4android

MS timezone "Central America Standard Time" is transformed with DST

Opened this issue · 5 comments

ICS files with the timezone "Central America Standard Time", which should be the one used in Guatemala. It looks like it gets converted to Chicago, which may break summer time I think.

The problem seems to come from files generated from Outlook.

Example ICS file: internal

BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN
VERSION:2.0
METHOD:REQUEST
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VTIMEZONE
TZID:Central America Standard Time
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:-0600
TZOFFSETTO:-0600
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
ATTENDEE;CN="Richard Martinez";RSVP=TRUE:mailto:rmartinez@sisteco.biz
CLASS:PUBLIC
CREATED:20240703T151754Z
DESCRIPTION:test 2 \n\n
DTEND;TZID="Central America Standard Time":20240703T103000
DTSTAMP:20240703T151352Z
DTSTART;TZID="Central America Standard Time":20240703T100000
LAST-MODIFIED:20240703T151754Z
LOCATION:remoto
ORGANIZER;CN="Jose de San Martin Juarez":mailto:jmjuarez@santaana.com.gt
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=es-gt:Reunion prueba 2 Calendario Outlook
TRANSP:OPAQUE
UID:040000008200E00074C5B7101A82E00800000000C08BCB4229CDDA01000000000000000
	010000000D3656D305AAF6A448B2B7D02C21E2448
X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//E
	N">\n<HTML>\n<HEAD>\n\n<META NAME="Generator" CONTENT="MS Exchange Server 
	version 16.0.17726.20016">\n<TITLE></TITLE>\n</HEAD>\n<BODY>\n<!-- Convert
	ed from text/rtf format -->\n\n<P><FONT FACE="Aptos">test 2</FONT>\n</P>\n
	\n</BODY>\n</HTML>
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-APPTSEQTIME:20240703T151352Z
X-MS-OLK-AUTOFILLLOCATION:FALSE
X-MS-OLK-CONFTYPE:0
BEGIN:VALARM
TRIGGER:-PT10M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

Depends on ical4j/ical4j#709

To reproduce:

@Test
fun testGuatemala() {
    javaClass.classLoader!!.getResourceAsStream("events/guatemala.ics").use { stream ->
        val events = Event.eventsFromReader(InputStreamReader(stream, Charsets.UTF_8))
        assertEquals(1, events.size)
        val event = events[0]
        event.dtStart!!.let { start ->
            val instant = Instant.ofEpochMilli(start.date.time)
            val dateTime = instant.atZone(ZoneId.of("America/Guatemala"))
            println(start.timeZone.id)
            assertEquals(
                ZonedDateTime.of(2024, 7, 3, 10, 0, 0, 0, ZoneId.of("America/Guatemala")),
                dateTime
            )
        }
    }
}

Fails with:

expected:<2024-07-03T10:00-06:00[America/Guatemala]>
but was: <2024-07-03T09:00-06:00[America/Guatemala]>

In any case, I think the timezone is directly not correctly defined in the ics. It doesn't specify any daylight saving, and "Central America Standard Time" is ambiguous I think, so that may be the issue here.

I agree:

  1. Central America Standard Time is mapped to US/Central by the MS timezone transformation rules. The transformation happens before evaluating the actual MS timezone.
  2. US/Central is an alias for America/Chicago. So the DTSTART is treated as if would have America/Chicago timezone.
  3. America/Chicago has DST, while Central America Standard Time apparently doesn't (at least given the original VTIMEZONE and some non 100% reliable information on the Web).
  4. So this causes the one-hour difference because the event is in summer so DST is applied.

I also found a table on unicode.org that suggests these mappings:

Central America Standard Time	001	America/Guatemala
Central America Standard Time	BZ	America/Belize
Central America Standard Time	CR	America/Costa_Rica
Central America Standard Time	EC	Pacific/Galapagos
Central America Standard Time	GT	America/Guatemala
Central America Standard Time	HN	America/Tegucigalpa
Central America Standard Time	NI	America/Managua
Central America Standard Time	SV	America/El_Salvador
Central America Standard Time	ZZ	Etc/GMT+6

I think Etc/GMT+6 would be the best choice because it's generic (although Etc/GMT+6 with plus actually means -06:00), or one of the cities/countries if it must be a city/country.

So as I understand it, this would have to be updated in ical4j in the MS outlook mapping file. @ArnyminerZ Can you please prepare an issue/PR for ical4j and link it as dependency?

Okay, I'll open a PR for that, however, I don't know if it will be released on 3.* knowing that 4.* is already stable...

This PR/issue depends on: