[horde] ActiveSync -> CalDAV Timezone problems

Steffen skhorde at smail.inf.fh-bonn-rhein-sieg.de
Tue Mar 22 15:33:10 UTC 2016


On Fri, 18 Mar 2016, Michael J Rubinsky wrote:
> Quoting Steffen <skhorde at smail.inf.fh-bonn-rhein-sieg.de>:
>
>> On Thu, 17 Mar 2016, Michael J Rubinsky wrote:
>>> Quoting Michael J Rubinsky <mrubinsk at horde.org>:
>>> 
>>>> Quoting Steffen <skhorde at smail.inf.fh-bonn-rhein-sieg.de>:
>>>> 
>>>>> On Wed, 16 Mar 2016, Michael J Rubinsky wrote:
>>>>>> Quoting Jan Schneider <jan at horde.org>:
>>>>>> 
>>>>>>> Zitat von Jan Schneider <jan at horde.org>:
>>>>>>> 
>>>>>>>> Zitat von Steffen <skhorde at smail.inf.fh-bonn-rhein-sieg.de>:
>>>>>>>> 
>>>>>>>>> Hi,
>>>>>>>>> 
>>>>>>>>> with
>>>>>>>>> Horde_ActiveSync             2.31.6  stable
>>>>>>>>> kronolith                    4.2.15  stable
>>>>>>>>> 
>>>>>>>>> when I create an event with Android ActiveSync, I get an entry with 
>>>>>>>>> event_timezone = 'CET' in the database; the GUI and ActiveSync 
>>>>>>>>> display the event correctly. But when downloaded by CalDAV I get 
>>>>>>>>> this:
>>>>>>>>> 
>>>>>>>>> BEGIN:VCALENDAR
>>>>>>>>> VERSION:2.0
>>>>>>>>> X-WR-CALNAME:Calendar of dvtest1
>>>>>>>>> PRODID:-//The Horde Project//Horde iCalendar Library//EN
>>>>>>>>> BEGIN:VEVENT
>>>>>>>>> DTSTART;TZID=CET:20160308T150000
>>>>>>>>> DTEND;TZID=CET:20160308T153000
>>>>>>>>> DTSTAMP:20160314T123714Z
>>>>>>>>> UID:20160314132443.4C_Xp8mUFWBF6GsNZi0nVRb at ...
>>>>>>>>> CREATED:20160314T122443Z
>>>>>>>>> LAST-MODIFIED:20160314T122443Z
>>>>>>>>> SUMMARY:B15:00
>>>>>>>>> CLASS:PUBLIC
>>>>>>>>> STATUS:CONFIRMED
>>>>>>>>> TRANSP:OPAQUE
>>>>>>>>> BEGIN:VALARM
>>>>>>>>> ACTION:DISPLAY
>>>>>>>>> DESCRIPTION:B15:00
>>>>>>>>> TRIGGER;VALUE=DURATION:-PT15M
>>>>>>>>> END:VALARM
>>>>>>>>> END:VEVENT
>>>>>>>>> BEGIN:VTIMEZONE
>>>>>>>>> TZID:CET
>>>>>>>>> END:VTIMEZONE
>>>>>>>>> END:VCALENDAR
>>>>>>>>> 
>>>>>>>>> My client is totally confused by the timezone CET. If I replace the 
>>>>>>>>> string CET by "Europe/Berlin" in the database, I get the correct 
>>>>>>>>> date in the CalDAV client, too, and a lot more entries in VTIMEZONE.
>>>>>>>>> 
>>>>>>>>> The user has Europe/Berlin as default timezone, as does PHP.
>>>>>>>>> 
>>>>>>>>> Is this some configuration error?
>>>>>>>>> If I remember correctly, ActiveSync storred UTC as timezone, didn't 
>>>>>>>>> it?
>>>>>>>>> 
>>>>>>>>> -- 
>>>>>>>>> Steffen
>>>>>>>> 
>>>>>>>> Looks like starting with PHP 5.5.10 DateTimeZone no longer converts 
>>>>>>>> timezone abbreviations to full timezone names, which is of course a 
>>>>>>>> big BC break. We would have to work around this.
>>>>>>> 
>>>>>>> OTOH we don't import unknown timezones anyway, at least not via 
>>>>>>> iCalendar import. But maybe we do this differently with ActiveSync. 
>>>>>>> Michael does know better.
>>>>>> 
>>>>>> Timezones from ActiveSync clients are presented in an MAPI encoded 
>>>>>> binary format that describes the timezone instead of naming it. We use 
>>>>>> DateTimeZone::listIdentifiers to retrieve the list of supported 
>>>>>> timezones when parsing the MAPI data to determine the 
>>>>>> matching/supported timezone name. So, if the timezone name comes from 
>>>>>> ActiveSync it means is MUST have been returned by DateTimeZone.
>>> 
>>> A more detailed explanation for the record:
>>> 
>>> EAS does not use timezone names/aliases at all. It only uses a single set 
>>> of transition dates that describe the timezone. It's up to the 
>>> client/server to translate that into timezone data it can use. For 
>>> Horde/PHP this means we have to translate it into a "standard" identifier 
>>> (as used in the Olson database). The reasons that this is a broken design 
>>> is a different discussion altogether.
>>> 
>>> Anyway, the problem here is that since all we have is a SINGLE set of 
>>> transition times, there will almost always be multiple timezone names that 
>>> will match when attempting to map the transitions to known zones. This is 
>>> why we check if we have an expected timezone and return it if it's in the 
>>> list of matched zones. What's happening for you is that since the timezone 
>>> data is incorrect for your expected timezone it's not in the list so we 
>>> return the more generic timezone alias/abbreviation - CET in your case. 
>>> FWIW, anytime there is an event in a timezone that is different from 
>>> date_default_timezone this will happen. So, while in your case the CET 
>>> being returned is the result of broken client data - it's not an 
>>> unexpected value to be returned.
>> 
>> The CalDAV implementation chokes on "CET". So the function
>> 
>> Horde/Mapi/Timezone.php getTimezone() should
>> 
>> return key($timezones); // to return some valid name
>> -or-
>> return "UTC";		// what's understood by CalDAV as well
>> 
>> or somewhere some mapping of CET must take place.
>> 
>>> For Horde 6 we could look at returning the full list of matching timezones 
>>> and let the calling code be responsible for picking the best match. This 
>>> might be more flexible, but still wouldn't help in this case - we still 
>>> would have no idea which Olson timezone name is correct so the abbreviated 
>>> alias would be the better choice.
>> 
>> Hmm, I though from read your links in Horde/ActiveSync/Timezone.php
>
> FYI, this class is deprecated - replaced by Horde_Mapi_Timezone though they 
> are mostly the same code.
>
>> that the data passed as timezone are related to the event: "The Timezone 
>> element is an optional element that specifies the time zone of the calendar 
>> item."
>
> Yes, this is correct. Though the better way to word that would probably be 
> "*describes* the timezone of the calendar item." It doesn't *name* the 
> timezone, it uses a hex encoded binary blob that contains various datetime 
> structs that represent a pair of transition times. It only provides a single 
> set of transition times that represent the current recurrence rules for the 
> timezone. E.g., DST transitions on the last Sunday of March. We take these 
> transition times and check them against a list of known recurrence rules for 
> known timezones to find the best match.
>
>
>> But the client passes a string, which is valid for 2016 (the current year 
>> it seems) no matter if the event is in 2015, 2016 or 2017. :-(
>
> This is incorrect. The year of the event is irrelevant. The correct rule for 
> the timezone is the LAST Sunday of the month and this is represented by a "5" 
> for the dstweek value. Your client is putting a "4" for that value so that it 
> will only match when month has 4 Sundays in it. I.e., a "4" means to always 
> match the 4th week, regardless of the number of weeks while a "5" means match 
> the 5th week in months with 5 or the 4th week if less than 5.
>
>> I will try to return "UTC" in getTimezone() for now and see where this gets 
>> me.
>
> This will likely screw up all of your events - making them off by whatever 
> the UTC offset of your timezone is.
>
> FWIW, the current Git code should now work correctly in the cases where CET 
> was returned for you. The new code will probably be released sometime this 
> weekend. Horde_Date and Horde_Mapi are the affected packages.

I also confirm that with the current PEAR versions of Horde ActiveSync 
events are now sync'ed correctly to CalDAV clients. They get UTC now, 
although the timezone returned by the code mentioned by 0x90 return 
"Europe/Berlin".

Thank you,

-- 
Steffen


More information about the horde mailing list