zpush caldav backend timezone issue

Hello,

I wanna using z-push to my own backend.(z-push 2.4.3)

But, when i check wbxml log, encoded timezone is weird and can not decode.

My windows timezone is Asia/Seoul

wbxml on activeSync is below and hope you give me some advice.

05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <DeletesAsMoves>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 0
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </DeletesAsMoves>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <GetChanges>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 0
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </GetChanges>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <WindowSize>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 512
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </WindowSize>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <Options>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <FilterType>
05/11/2018 06:28:23 [ 2102] [DEBUG] [seungyon.yeo] SyncParameters->UseCPO(‘DEFAULT’)
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 0
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </FilterType>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I AirSyncBase:BodyPreference
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I AirSyncBase:Type
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 1
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </AirSyncBase:Type>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I AirSyncBase:AllOrNone
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 1
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </AirSyncBase:AllOrNone>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </AirSyncBase:BodyPreference>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </Options>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <Perform>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <Add>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <FolderType>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I Calendar
05/11/2018 06:28:23 [ 2102] [DEBUG] [seungyon.yeo] HandleSync(): incoming data with foldertype ‘Calendar’
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </FolderType>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <ClientEntryId>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I {AC7269AF-24B6-4D61-8C87-36778EF9AFCE}
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </ClientEntryId>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I <Data>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:Timezone
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 5P3//wCzXNX8u22tIABc1ADJ3MIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzXNX8u22tIAB8xxGtIAAIyH3FIADcwgSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///w==
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:Timezone>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:DtStamp
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 20181105T062816Z
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:DtStamp>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:StartTime
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 20181111T150000Z
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:StartTime>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:Subject
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 5
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:Subject>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:UID
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 040000008200E00074C5B7101A82E0080000000030B698321C75D401000000000000000010000000BB5EBFB2264A114AA7133462C73A039F
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:UID>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:EndTime
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 20181112T150000Z
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:EndTime>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:Sensitivity
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 0
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:Sensitivity>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:BusyStatus
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 0
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:BusyStatus>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:AllDayEvent
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 1
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:AllDayEvent>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I POOMCAL:MeetingStatus
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I 0
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </POOMCAL:MeetingStatus>
05/11/2018 06:28:23 [ 2102] [WBXML] [seungyon.yeo] I </Data>

Thanks a lot

Harold

Hi Harold,

Timezone tag is a base64 encoded string which contains time zone structure. See the MS documentation for the details: https://msdn.microsoft.com/en-us/library/ee204550(v=exchg.80).aspx.

The code below displays what information was saved in the tag

$tz = unpack(   "lbias/a64tzname/vdstendyear/vdstendmonth/vdstendday/vdstendweek/vdstendhour/vdstendminute/vdstendsecond/vdstendmillis/lstdbias/a64tznamedst/vdststartyear/vdststartmonth/vdststartday/vdststartweek/vdststarthour/vdststartminute/vdststartsecond/vdststartmillis/ldstbias", base64_decode($timezone));

where $timezone is the POOMCAL:Timezone value (“5P3//wCzXNX8u22tIABc1ADJ3M…”).

It’s possible that $tz[‘tzname’] won’t contain ‘Asia/Seoul’ and you have to do further conversion/mapping. timezoneutils.php in lib/utils/ of Z-Push contains several functions which do similar conversions.

Manfred

Hi Manfred,

First of all, thank you for reply to my post.

Now, i have another question. src/backend/caldav/caldav.php line 1503 code is "if ($str == $tz_string) "

That means return default timezone if ‘wbxml timezone’ is different from ‘packed timezone string’.

But, when i check Asia/Seoul timezone packed string, It’s different from wbxml timezone string.(not only Asia/seoul, but also other timezone)

wbxml timezone string is
‘5P3//wCzXNX8u22tIABc1ADJ3MIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzXNX8u22tIAB8xxGtIAAIyH3FIADcwgSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==’

But packed string is
‘5P3//ygARwBNAFQAKwAwADkAOgAwADAAKQAgAFMAZQBvAHUAbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgARwBNAFQAKwAwADkAOgAwADAAKQAgAFMAZQBvAHUAbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///w==’

It looks similar but different.

Should i change something on outlook 2013?

code is below and log is too.

Code 
private function _GetTimezoneFromString($tz_string) {
	//unpack tz_string
	$unpacktz = unpack(   "lbias/a64tzname/vdstendyear/vdstendmonth/vdstendday/vdstendweek/vdstendhour/vdstendminute/vdstendsecond/vdstendmillis/lstdbias/a64tznamedst/vdststartyear/vdststartmonth/vdststartday/vdststartweek/vdststarthour/vdststartminute/vdststartsecond/vdststartmillis/ldstbias", base64_decode($tz_string));
	ZLog::Write(LOGLEVEL_INFO, sprintf("BackendCalDAV->_GetTimezoneFromString(): Unpack '%s' timezone", $tz_string));
	ZLog::Write(LOGLEVEL_INFO, sprintf("BackendCalDAV->_GetTimezoneFromString(): Unpack '%s' timezone", $unpacktz['tzname']));
			
    //Get a list of all timezones
    $identifiers = DateTimeZone::listIdentifiers();
    //Try the default timezone first
    array_unshift($identifiers, date_default_timezone_get());
    foreach ($identifiers as $tz) {
        $str = $this->_GetTimezoneString($tz, false);
        if($tz == 'Asia/Seoul'){
        	$unpacktz = unpack(   "lbias/a64tzname/vdstendyear/vdstendmonth/vdstendday/vdstendweek/vdstendhour/vdstendminute/vdstendsecond/vdstendmillis/lstdbias/a64tznamedst/vdststartyear/vdststartmonth/vdststartday/vdststartweek/vdststarthour/vdststartminute/vdststartsecond/vdststartmillis/ldstbias", base64_decode($str));
			ZLog::Write(LOGLEVEL_INFO, sprintf("BackendCalDAV->_GetTimezoneFromString(): Unpack '%s' timezone", $str));
			ZLog::Write(LOGLEVEL_INFO, sprintf("BackendCalDAV->_GetTimezoneFromString(): Unpack '%s' timezone", $unpacktz['tzname']));
        }
        if ($str == $tz_string) {
            ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendCalDAV->_GetTimezoneFromString(): Found timezone: '%s'.", $tz));
            return $tz;
        }
    }
    return date_default_timezone_get();
}

LOG 
06/11/2018 02:58:34 [30438] [ INFO] [seungyon.yeo] BackendCalDAV->_GetTimezoneFromString(): Unpack '5P3//wCzXNX8u22tIABc1ADJ3MIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzXNX8u22tIAB8xxGtIAAIyH3FIADcwgSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==' timezone
06/11/2018 02:58:34 [30438] [ INFO] [seungyon.yeo] BackendCalDAV->_GetTimezoneFromString(): Unpack '^@쨀\횛체쨩m짯 ^@\횚^@횋횥횂' timezone
06/11/2018 02:58:34 [30438] [ INFO] [seungyon.yeo] BackendCalDAV->_GetTimezoneFromString(): Unpack '5P3//ygARwBNAFQAKwAwADkAOgAwADAAKQAgAFMAZQBvAHUAbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgARwBNAFQAKwAwADkAOgAwADAAKQAgAFMAZQBvAHUAbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///w==' timezone
06/11/2018 02:58:34 [30438] [ INFO] [seungyon.yeo] BackendCalDAV->_GetTimezoneFromString(): Unpack '(^@G^@M^@T^@+^@0^@9^@:^@0^@0^@)^@ ^@S^@e^@o^@u^@l' timezone

Hi Harold,

the caldav backend is a community contribution and I’m not very familiar with it. I also don’t speak Korean, so I’ve no idea what ‘^@쨀\횛체쨩m짯 ^@\횚^@횋횥횂’ means or if it even makes sense. I have also no idea what the mobile packs into the timezone description which is in the incoming timezone tag.
I guess though that WBXML timezone and packed are different because one contains “Korea Standard Time” (’^@쨀\횛체쨩m짯 ^@\횚^@횋횥횂’) and another “(GMT+09:00) Seoul”. And in PHP it’s “Asia/Seoul”.
The timezone handling is tricky because PHP timezones doesn’t match Windows timezones, so you have to map them which can lead to inaccuracies.

Could you explain your use case more detailed? Does it involve only Outlook syncing to some groupware or do you also want to sync mobile devices?

Manfred