diff --git a/lib/kolab_sync_data_tasks.php b/lib/kolab_sync_data_tasks.php --- a/lib/kolab_sync_data_tasks.php +++ b/lib/kolab_sync_data_tasks.php @@ -164,6 +164,28 @@ return $as_array ? $result : new Syncroton_Model_Task($result); } + + + /** + * Returns a timezone with an offset matching the difference between $d1 and $d2 + */ + private static function getOffsetTimezone($d1, $d2) + { + $interval = $d1->diff($d2); + $tz = new DateTimeZone($interval->format('%R%H%I')); //e.g. +0200 + $utcOffset = $tz->getOffset(new DateTime('now', $timezone)); + //Look for a timezone with a matching offset. We can't store offsets directly + foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) { + $timezone = new DateTimeZone($timezoneIdentifier); + $dt = new DateTime('now', $timezone); + if ($timezone->getOffset($dt) == $utcOffset) { + return $timezone; + } + } + return null; + } + + /** * convert contact from xml to libkolab array * @@ -186,6 +208,25 @@ $value = $data->$key; switch ($name) { + + case 'due': + case 'start': + // We expect to always get regular and utc variants, so we only need to take one into account. + if ($key == 'utcStartDate' || $key == 'utcDueDate') { + continue 2; + } + if ($value) { + if ($name =='due' && $data->utcDueDate) { + $tz = static::getOffsetTimezone($data->utcDueDate, $value); + if ($tz) { + //Setting the timezone will change the time, so we set it on the utc variant instead to end up with what we want. + $value = $data->utcDueDate; + $value->setTimezone($tz); + } + } + } + break; + case 'sensitivity': $map = array_flip($this->sensitivityMap); $value = $map[$value];