mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-29 11:23:54 +01:00
"Using VTIMEZONE component from new calendar_timezones class (imported sqlite DB from Lighting) for exports and importing TZID from iCals.
Horde Code already uses VTIMEZONE component to return times in servertime, no need to change anything there."
This commit is contained in:
parent
90d5815dfa
commit
85bf743434
@ -198,20 +198,18 @@ class calendar_ical extends calendar_boupdate
|
|||||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||||
$vcal->setAttribute('VERSION', $version);
|
$vcal->setAttribute('VERSION', $version);
|
||||||
$vcal->setAttribute('METHOD', $method);
|
$vcal->setAttribute('METHOD', $method);
|
||||||
$serverTZ = false;
|
|
||||||
|
|
||||||
if (!is_array($events)) $events = array($events);
|
if (!is_array($events)) $events = array($events);
|
||||||
|
|
||||||
while (($event = array_pop($events)))
|
$vtimezones_added = array();
|
||||||
|
foreach($events as $event)
|
||||||
{
|
{
|
||||||
if (strpos($this->productName, 'palmos'))
|
if (strpos($this->productName, 'palmos') !== false)
|
||||||
{
|
{
|
||||||
$utc = false;
|
|
||||||
$date_format = 'ts';
|
$date_format = 'ts';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$utc = true;
|
|
||||||
$date_format = 'server';
|
$date_format = 'server';
|
||||||
}
|
}
|
||||||
if (!is_array($event)
|
if (!is_array($event)
|
||||||
@ -236,34 +234,31 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
if ($this->log) error_log(__FILE__.'('.__LINE__.'): '.__METHOD__.' '.array2string($event)."\n",3,$this->logfile);
|
if ($this->log) error_log(__FILE__.'('.__LINE__.'): '.__METHOD__.' '.array2string($event)."\n",3,$this->logfile);
|
||||||
|
|
||||||
if (!$serverTZ
|
// for palmos we have to use user-time and NO timezone
|
||||||
&& $event['recur_type'] != MCAL_RECUR_NONE
|
if (strpos($this->productName, 'palmos') !== false)
|
||||||
&& date('e', $event['start']) != 'UTC')
|
|
||||||
{
|
{
|
||||||
if ($event['recur_enddate'])
|
$tzid = null;
|
||||||
|
}
|
||||||
|
// check if tzid of event (not only recuring ones) is already added to export
|
||||||
|
elseif (($tzid = $event['tzid']) && $tzid != 'UTC' && !in_array($tzid,$vtimezones_added))
|
||||||
|
{
|
||||||
|
// check if we have vtimezone component data for tzid of event, if not default to user timezone (default to server tz)
|
||||||
|
if (!($vtimezone = calendar_timezones::tz2id($tzid,'component')))
|
||||||
{
|
{
|
||||||
$startDST = date('I', $event['start']);
|
error_log(__METHOD__."() unknown TZID='$tzid', defaulting to user timezone '".egw_time::$user_timezone->getName()."'!");
|
||||||
$finalDST = date('I', $event['recur_enddate']);
|
$vtimezone = calendar_timezones::tz2id($tzid=egw_time::$user_timezone->getName(),'component');
|
||||||
// Different DST or more than half a year?
|
|
||||||
if ($startDST != $finalDST ||
|
|
||||||
($event['recur_enddate'] - $event['start']) > 15778800)
|
|
||||||
{
|
|
||||||
$utc = false;
|
|
||||||
$serverTZ = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
//error_log("in_array('$tzid',\$vtimezones_added)=".array2string(in_array($tzid,$vtimezones_added)).", component=$vtimezone");;
|
||||||
|
if (!in_array($tzid,$vtimezones_added))
|
||||||
{
|
{
|
||||||
$utc = false;
|
// $vtimezone is a string with a single VTIMEZONE component, afaik Horde_iCalendar can not add it directly
|
||||||
$serverTZ = true;
|
// --> we have to parse it and let Horde_iCalendar add it again
|
||||||
}
|
$horde_vtimezone = Horde_iCalendar::newComponent('VTIMEZONE',$container=false);
|
||||||
if ($serverTZ)
|
$horde_vtimezone->parsevCalendar($vtimezone,'VTIMEZONE');
|
||||||
{
|
$vcal->addComponent($horde_vtimezone);
|
||||||
// Add only one instance
|
$vtimezones_added[] = $tzid;
|
||||||
$serverTZ = $this->generate_vtimezone($event, $vcal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->productManufacturer != 'file' && $this->uidExtension)
|
if ($this->productManufacturer != 'file' && $this->uidExtension)
|
||||||
{
|
{
|
||||||
// Append UID to DESCRIPTION
|
// Append UID to DESCRIPTION
|
||||||
@ -347,15 +342,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'DTSTART':
|
case 'DTSTART':
|
||||||
if ($utc)
|
$attributes['DTSTART'] = self::getDateTime($event['start'],$tzid,$parameters['DTSTART']);
|
||||||
{
|
|
||||||
$attributes['DTSTART'] = $event['start'];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$attributes['DTSTART'] = date('Ymd\THis', $event['start']);
|
|
||||||
if ($serverTZ) $parameters['DTSTART']['TZID'] = $serverTZ;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'DTEND':
|
case 'DTEND':
|
||||||
@ -373,15 +360,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ($utc)
|
$attributes['DTEND'] = self::getDateTime($event['end'],$tzid,$parameters['DTEND']);
|
||||||
{
|
|
||||||
$attributes['DTEND'] = $event['end'];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$attributes['DTEND'] = date('Ymd\THis', $event['end']);
|
|
||||||
if ($serverTZ) $parameters['DTEND']['TZID'] = $serverTZ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -516,18 +495,13 @@ class calendar_ical extends calendar_boupdate
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$value_type = 'DATE-TIME';
|
$value_type = 'DATE-TIME';
|
||||||
if (!$utc)
|
foreach ($days as &$timestamp)
|
||||||
{
|
{
|
||||||
foreach ($days as $id => $timestamp)
|
$timestamp = self::getDateTime($timestamp,$tzid,$parameters['EXDATE']);
|
||||||
{
|
|
||||||
$days[$id] = date('Ymd\THis', $timestamp);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$attributes['EXDATE'] = '';
|
$attributes['EXDATE'] = '';
|
||||||
$values['EXDATE'] = $days;
|
$values['EXDATE'] = $days;
|
||||||
if ($serverTZ) $parameters['EXDATE']['TZID'] = $serverTZ;
|
|
||||||
$parameters['EXDATE']['VALUE'] = $value_type;
|
$parameters['EXDATE']['VALUE'] = $value_type;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -575,15 +549,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ($utc)
|
$attributes[$icalFieldName] = self::getDateTime($recur_date,$tzid,$parameters[$icalFieldName]);
|
||||||
{
|
|
||||||
$attributes[$icalFieldName] = $recur_date;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$attributes[$icalFieldName] = date('Ymd\THis', $recur_date);
|
|
||||||
if ($serverTZ) $parameters[$icalFieldName]['TZID'] = $serverTZ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif ($event['recurrence'] && $event['reference'])
|
elseif ($event['recurrence'] && $event['reference'])
|
||||||
@ -603,15 +569,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ($utc)
|
$attributes[$icalFieldName] = self::getDateTime($recur_date,$tzid,$parameters[$icalFieldName]);
|
||||||
{
|
|
||||||
$attributes[$icalFieldName] = $event['recurrence'];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$attributes[$icalFieldName] = date('Ymd\THis', $event['recurrence']);
|
|
||||||
if ($serverTZ) $parameters[$icalFieldName]['TZID'] = $serverTZ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
unset($revent);
|
unset($revent);
|
||||||
}
|
}
|
||||||
@ -693,18 +651,8 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
if ($version == '1.0')
|
if ($version == '1.0')
|
||||||
{
|
{
|
||||||
if ($utc)
|
$attributes['DALARM'] = self::getDateTime($alarmData['time'],$tzid,$parameters['DALARM']);
|
||||||
{
|
$attributes['AALARM'] = self::getDateTime($alarmData['time'],$tzid,$parameters['AALARM']);
|
||||||
$attributes['DALARM'] = $alarmData['time'];
|
|
||||||
$attributes['AALARM'] = $alarmData['time'];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$attributes['DALARM'] = date('Ymd\THis', $alarmData['time']);
|
|
||||||
if ($serverTZ) $parameters['DALARM']['TZID'] = $serverTZ;
|
|
||||||
$attributes['AALARM'] = date('Ymd\THis', $alarmData['time']);
|
|
||||||
if ($serverTZ) $parameters['AALARM']['TZID'] = $serverTZ;
|
|
||||||
}
|
|
||||||
// lets take only the first alarm
|
// lets take only the first alarm
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -735,15 +683,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$params = array('VALUE' => 'DATE-TIME');
|
$params = array('VALUE' => 'DATE-TIME');
|
||||||
if ($utc)
|
$value = self::getDateTime($alarmData['time'],$tzid,$params);
|
||||||
{
|
|
||||||
$value = $alarmData['time'];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$value = date('Ymd\THis', $alarmData['time']);
|
|
||||||
if ($serverTZ) $params['TZID'] = $serverTZ;
|
|
||||||
}
|
|
||||||
$valarm->setAttribute('TRIGGER', $value, $params);
|
$valarm->setAttribute('TRIGGER', $value, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,6 +730,36 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get DateTime value for a given time and timezone
|
||||||
|
*
|
||||||
|
* @param int|string|DateTime $time in server-time as returned by calendar_bo for $data_format='server'
|
||||||
|
* @param string $tzid TZID of event or 'UTC' or NULL for palmos timestamps in usertime
|
||||||
|
* @param array &$params=null parameter array to set TZID
|
||||||
|
* @return mixed attribute value to set: integer timestamp if $tzid == 'UTC' otherwise Ymd\THis string IN $tzid
|
||||||
|
*/
|
||||||
|
static function getDateTime($time,$tzid,array &$params=null)
|
||||||
|
{
|
||||||
|
if (empty($tzid) || $tzid == 'UTC')
|
||||||
|
{
|
||||||
|
return egw_time::to($time,'ts');
|
||||||
|
}
|
||||||
|
if (!is_a($time,'DateTime'))
|
||||||
|
{
|
||||||
|
$time = new egw_time($time,egw_time::$server_timezone);
|
||||||
|
}
|
||||||
|
static $timezone;
|
||||||
|
static $timezone_tzid;
|
||||||
|
if (is_null($timezone) || $timezone_tzid != $tzid)
|
||||||
|
{
|
||||||
|
$timezone = new DateTimeZone($timezone_tzid = $tzid);
|
||||||
|
}
|
||||||
|
$time->setTimezone($timezone);
|
||||||
|
$params['TZID'] = $tzid;
|
||||||
|
|
||||||
|
return $time->format('Ymd\THis');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import an iCal
|
* Import an iCal
|
||||||
*
|
*
|
||||||
@ -1531,6 +1501,21 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
$dtstart_ts = is_numeric($attributes['value']) ? $attributes['value'] : $this->date2ts($attributes['value']);
|
$dtstart_ts = is_numeric($attributes['value']) ? $attributes['value'] : $this->date2ts($attributes['value']);
|
||||||
$vcardData['start'] = $dtstart_ts;
|
$vcardData['start'] = $dtstart_ts;
|
||||||
|
|
||||||
|
// import TZID, if PHP understands it (we only care about TZID of starttime, as we store only a TZID for the whole event)
|
||||||
|
if (!empty($attributes['params']['TZID']))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$tz = new DateTimeZone($attributes['params']['TZID']);
|
||||||
|
$event['tzid'] = $tz->getName();
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
error_log(__METHOD__."() unknown TZID='{$attributes['params']['TZID']}', defaulting to user timezone '".egw_time::$user_timezone->getName()."'!");
|
||||||
|
$event['tzid'] = egw_time::$user_timezone->getName(); // default to user timezone
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'DTEND':
|
case 'DTEND':
|
||||||
$dtend_ts = is_numeric($attributes['value']) ? $attributes['value'] : $this->date2ts($attributes['value']);
|
$dtend_ts = is_numeric($attributes['value']) ? $attributes['value'] : $this->date2ts($attributes['value']);
|
||||||
@ -2317,342 +2302,4 @@ class calendar_ical extends calendar_boupdate
|
|||||||
'master_event' => $return_master ? $master_event : false,
|
'master_event' => $return_master ? $master_event : false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* generate and insert a VTIMEZONE entry to a vcalendar
|
|
||||||
*
|
|
||||||
* @param array $event
|
|
||||||
* @param array $vcal VCALENDAR entry
|
|
||||||
* @return string local timezone name (e.g. 'CET/CEST')
|
|
||||||
*/
|
|
||||||
function generate_vtimezone($event, &$vcal)
|
|
||||||
{
|
|
||||||
$dayofweek = array('SU','MO','TU','WE','TH','FR','SA');
|
|
||||||
$tbl_tz = array(
|
|
||||||
array("Afghanistan","Asia/Kabul",270,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("AKST/AKDT","America/Anchorage",-540,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("AKST/AKDT","America/Anchorage",-540,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("AKST/AKDT","America/Anchorage",-540,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNY/NAY","America/Anchorage",-540,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNY/NAY","America/Anchorage",-540,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("HNY/NAY","America/Anchorage",-540,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Alaskan","America/Anchorage",-540,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Alaskan","America/Anchorage",-540,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Alaskan","America/Anchorage",-540,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Arab","Asia/Riyadh",180,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Arabian","Asia/Dubai",240,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Arabic","Asia/Baghdad",180,60,"",4,0,1,3,0,10,0,1,4,0),
|
|
||||||
array("AST/ADT","America/Halifax",-240,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("AST/ADT","America/Halifax",-240,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("AST/ADT","America/Halifax",-240,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNA/HAA","America/Halifax",-240,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNA/HAA","America/Halifax",-240,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("HNA/HAA","America/Halifax",-240,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Atlantic","America/Halifax",-240,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Atlantic","America/Halifax",-240,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Atlantic","America/Halifax",-240,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("AUS_Central","Australia/Darwin",570,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("AUS_Eastern","Australia/Sydney",600,60,"",10,0,5,2,0,3,0,5,3,0),
|
|
||||||
array("Azerbaijan","Asia/Baku",240,60,"",3,0,5,4,0,10,0,5,5,0),
|
|
||||||
array("Azores","Atlantic/Azores",-60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Canada_Central","America/Regina",-360,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Cape_Verde","Atlantic/Cape_Verde",-60,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Caucasus","Asia/Tbilisi",240,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("ACST/ACDT","Australia/Adelaide",570,60,"",10,0,5,2,0,3,0,5,3,0),
|
|
||||||
array("Central_Australia","Australia/Adelaide",570,60,"",10,0,5,2,0,3,0,5,3,0),
|
|
||||||
array("Central_America","America/Guatemala",-360,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Central_Asia","Asia/Dhaka",360,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Central_Brazilian","America/Manaus",-240,60,"",11,0,1,0,0,2,0,5,0,0),
|
|
||||||
array("Central_Brazilian","America/Manaus",-240,60,"2006",11,0,1,0,0,2,0,2,2,0),
|
|
||||||
array("Central_Brazilian","America/Manaus",-240,60,"2007",11,0,1,0,0,2,0,5,0,0),
|
|
||||||
array("CET/CEST","Europe/Zurich",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("CET/CEST","Europe/Vienna",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("MEZ/MESZ","Europe/Berlin",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Central_Europe","Europe/Budapest",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Central_European","Europe/Warsaw",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Central_Pacific","Pacific/Guadalcanal",660,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("CST/CDT","America/Chicago",-360,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("CST/CDT","America/Chicago",-360,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("CST/CDT","America/Chicago",-360,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNC/HAC","America/Chicago",-360,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNC/HAC","America/Chicago",-360,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("HNC/HAC","America/Chicago",-360,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Central","America/Chicago",-360,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Central","America/Chicago",-360,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Central","America/Chicago",-360,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Central_Mexico","America/Mexico_City",-360,60,"",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("China","Asia/Shanghai",480,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Dateline","Etc/GMT+12",-720,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("East_Africa","Africa/Nairobi",180,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("AEST/AEDT","Australia/Brisbane",600,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("East_Australia","Australia/Brisbane",600,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("EET/EEST","Europe/Minsk",120,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("EET/EEST","Europe/Helsinki",120,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("East_Europe","Europe/Minsk",120,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("East_South_America","America/Sao_Paulo",-180,60,"",11,0,1,0,0,2,0,5,0,0),
|
|
||||||
array("East_South_America","America/Sao_Paulo",-180,60,"2006",11,0,1,0,0,2,0,2,2,0),
|
|
||||||
array("East_South_America","America/Sao_Paulo",-180,60,"2007",11,0,1,0,0,2,0,5,0,0),
|
|
||||||
array("EST/EDT","America/New_York",-300,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("EST/EDT","America/New_York",-300,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("EST/EDT","America/New_York",-300,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNE/HAE","America/New_York",-300,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNE/HAE","America/New_York",-300,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("HNE/HAE","America/New_York",-300,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Eastern","America/New_York",-300,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Eastern","America/New_York",-300,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Eastern","America/New_York",-300,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Egypt","Africa/Cairo",120,60,"",4,4,5,23,59,9,4,5,23,59),
|
|
||||||
array("Ekaterinburg","Asia/Yekaterinburg",300,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Fiji","Pacific/Fiji",720,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("FLE","Europe/Kiev",120,60,"",3,0,5,3,0,10,0,5,4,0),
|
|
||||||
array("Georgian","Etc/GMT-3",180,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("GMT","Europe/London",0,60,"",3,0,5,1,0,10,0,5,2,0),
|
|
||||||
array("Greenland","America/Godthab",-180,60,"",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Greenwich","Africa/Casablanca",0,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("GTB","Europe/Istanbul",120,60,"",3,0,5,3,0,10,0,5,4,0),
|
|
||||||
array("HAST/HADT","Pacific/Honolulu",-600,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Hawaiian","Pacific/Honolulu",-600,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("India","Asia/Calcutta",330,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Iran","Asia/Tehran",210,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Iran","Asia/Tehran",210,60,"2005",3,0,1,2,0,9,2,4,2,0),
|
|
||||||
array("Iran","Asia/Tehran",210,0,"2006",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"",3,5,5,2,0,9,0,3,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,0,"2004",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2005",4,-1,1,2,0,10,-1,9,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2006",3,-1,31,2,0,10,-1,1,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2007",3,-1,30,2,0,9,-1,16,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2008",3,-1,28,2,0,10,-1,5,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2009",3,-1,27,2,0,9,-1,27,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2010",3,-1,26,2,0,9,-1,12,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2011",4,-1,1,2,0,10,-1,2,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2012",3,-1,30,2,0,9,-1,23,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2013",3,-1,29,2,0,9,-1,8,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2014",3,-1,28,2,0,9,-1,28,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2015",3,-1,27,2,0,9,-1,20,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2016",4,-1,1,2,0,10,-1,9,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2017",3,-1,31,2,0,9,-1,24,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2018",3,-1,30,2,0,9,-1,16,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2019",3,-1,29,2,0,10,-1,6,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2020",3,-1,27,2,0,9,-1,27,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2021",3,-1,26,2,0,9,-1,12,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,60,"2022",4,-1,1,2,0,10,-1,2,2,0),
|
|
||||||
array("Israel","Asia/Jerusalem",120,0,"2023",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Jordan","Asia/Amman",120,60,"",3,4,5,0,0,9,5,5,1,0),
|
|
||||||
array("Korea","Asia/Seoul",540,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Mexico","America/Mexico_City",-360,60,"",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Mexico_2","America/Chihuahua",-420,60,"",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Mid_Atlantic","Atlantic/South_Georgia",-120,60,"",3,0,5,2,0,9,0,5,2,0),
|
|
||||||
array("Middle_East","Asia/Beirut",120,60,"",3,0,5,0,0,10,6,5,23,59),
|
|
||||||
array("Montevideo","America/Montevideo",-180,60,"",10,0,1,2,0,3,0,2,2,0),
|
|
||||||
array("MST/MDT","America/Denver",-420,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("MST/MDT","America/Denver",-420,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("MST/MDT","America/Denver",-420,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNR/HAR","America/Denver",-420,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNR/HAR","America/Denver",-420,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("HNR/HAR","America/Denver",-420,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Mountain","America/Denver",-420,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Mountain","America/Denver",-420,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Mountain","America/Denver",-420,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Mountain_Mexico","America/Chihuahua",-420,60,"",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Myanmar","Asia/Rangoon",390,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("North_Central_Asia","Asia/Novosibirsk",360,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Namibia","Africa/Windhoek",120,-60,"",4,0,1,2,0,9,0,1,2,0),
|
|
||||||
array("Nepal","Asia/Katmandu",345,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("New_Zealand","Pacific/Auckland",720,60,"",10,0,1,2,0,3,0,3,3,0),
|
|
||||||
array("NST/NDT","America/St_Johns",-210,60,"",3,0,2,0,1,11,0,1,0,1),
|
|
||||||
array("NST/NDT","America/St_Johns",-210,60,"2006",4,0,1,0,1,10,0,5,0,0),
|
|
||||||
array("NST/NDT","America/St_Johns",-210,60,"2007",3,0,2,0,1,11,0,1,0,0),
|
|
||||||
array("HNT/HAT","America/St_Johns",-210,60,"",3,0,2,0,1,11,0,1,0,1),
|
|
||||||
array("HNT/HAT","America/St_Johns",-210,60,"2006",4,0,1,0,1,10,0,5,0,0),
|
|
||||||
array("HNT/HAT","America/St_Johns",-210,60,"2007",3,0,2,0,1,11,0,1,0,0),
|
|
||||||
array("Newfoundland","America/St_Johns",-210,60,"",3,0,2,0,1,11,0,1,0,1),
|
|
||||||
array("Newfoundland","America/St_Johns",-210,60,"2006",4,0,1,0,1,10,0,5,0,0),
|
|
||||||
array("Newfoundland","America/St_Johns",-210,60,"2007",3,0,2,0,1,11,0,1,0,0),
|
|
||||||
array("North_Asia_East","Asia/Irkutsk",480,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("North_Asia","Asia/Krasnoyarsk",420,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Pacific_SA","America/Santiago",-240,60,"",10,6,2,23,59,3,6,2,23,59),
|
|
||||||
array("PST/PDT","America/Los_Angeles",-480,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("PST/PDT","America/Los_Angeles",-480,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("PST/PDT","America/Los_Angeles",-480,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNP/HAP","America/Los_Angeles",-480,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("HNP/HAP","America/Los_Angeles",-480,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("HNP/HAP","America/Los_Angeles",-480,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Pacific","America/Los_Angeles",-480,60,"",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Pacific","America/Los_Angeles",-480,60,"2006",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Pacific","America/Los_Angeles",-480,60,"2007",3,0,2,2,0,11,0,1,2,0),
|
|
||||||
array("Pacific_Mexico","America/Tijuana",-480,60,"",4,0,1,2,0,10,0,5,2,0),
|
|
||||||
array("Romance","Europe/Paris",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("Russian","Europe/Moscow",180,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("SA_Eastern","Etc/GMT+3",-180,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("SA_Pacific","America/Bogota",-300,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("SA_Western","America/La_Paz",-240,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Samoa","Pacific/Apia",-660,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("SE_Asia","Asia/Bangkok",420,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Singapore","Asia/Singapore",480,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("South_Africa","Africa/Johannesburg",120,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Sri_Lanka","Asia/Colombo",330,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Taipei","Asia/Taipei",480,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Tasmania","Australia/Hobart",600,60,"",10,0,1,2,0,3,0,5,3,0),
|
|
||||||
array("Tokyo","Asia/Tokyo",540,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Tonga","Pacific/Tongatapu",780,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("US_Eastern","Etc/GMT+5",-300,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("US_Mountain","America/Phoenix",-420,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Vladivostok","Asia/Vladivostok",600,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("West_Australia","Australia/Perth",480,60,"",10,0,5,2,0,3,0,5,3,0),
|
|
||||||
array("West_Australia","Australia/Perth",480,0,"2005",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("West_Australia","Australia/Perth",480,60,"2006",12,-1,1,2,0,1,-1,1,0,0),
|
|
||||||
array("West_Australia","Australia/Perth",480,60,"2007",10,0,5,2,0,3,0,5,3,0),
|
|
||||||
array("West_Central_Africa","Africa/Lagos",60,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("WET/WEST","Europe/Berlin",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("West_Europe","Europe/Berlin",60,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
array("West_Asia","Asia/Karachi",300,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("West_Pacific","Pacific/Port_Moresby",600,0,"",0,0,0,0,0,0,0,0,0,0),
|
|
||||||
array("Yakutsk","Asia/Yakutsk",540,60,"",3,0,5,2,0,10,0,5,3,0),
|
|
||||||
);
|
|
||||||
|
|
||||||
$serverTZ = date('e', $event['start']);
|
|
||||||
$year = date('Y', $event['start']);
|
|
||||||
$i = 0;
|
|
||||||
$row = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
$tbl_tz_row =& $tbl_tz[$i];
|
|
||||||
if ($tbl_tz_row[1] == $serverTZ)
|
|
||||||
{
|
|
||||||
if ($tbl_tz_row[4] == '' || $year >= (int) $tbl_tz_row[4])
|
|
||||||
{
|
|
||||||
$row = $i;
|
|
||||||
}
|
|
||||||
elseif ($row !== false) break;
|
|
||||||
elseif ($tbl_tz_row[4] != '' && $year < (int) $tbl_tz_row[4])
|
|
||||||
{
|
|
||||||
// First DST starts at this year
|
|
||||||
$year = (int) $tbl_tz_row[4];
|
|
||||||
if (empty($event['recur_enddate'])
|
|
||||||
|| $year <= date('Y', $event['recur_enddate']))
|
|
||||||
{
|
|
||||||
$row = $i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif ($row !== false) break;
|
|
||||||
}
|
|
||||||
while (is_array($tbl_tz[++$i]));
|
|
||||||
|
|
||||||
if ($row === false) return $serverTZ; // UTC or unkown TZ
|
|
||||||
|
|
||||||
$tbl_tz_row =& $tbl_tz[$row];
|
|
||||||
|
|
||||||
if (preg_match('/(.+)\/(.+)/', $tbl_tz_row[0], $matches))
|
|
||||||
{
|
|
||||||
$stdname = $matches[1];
|
|
||||||
$dstname = $matches[2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$stdname = $dstname = $tbl_tz_row[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
$container = false;
|
|
||||||
$vtimezone = Horde_iCalendar::newComponent('VTIMEZONE', $container);
|
|
||||||
$vtimezone->setAttribute('TZID', $tbl_tz_row[1]);
|
|
||||||
do {
|
|
||||||
if (is_array($tbl_tz[++$row]))
|
|
||||||
{
|
|
||||||
$tbl_next_row =& $tbl_tz[$row];
|
|
||||||
if ($tbl_next_row[1] != $serverTZ) $tbl_next_row = false;
|
|
||||||
}
|
|
||||||
else $tbl_next_row = false;
|
|
||||||
|
|
||||||
$minutes = $tbl_tz_row[2] + $tbl_tz_row[3];
|
|
||||||
$value1['ahead'] = ($minutes >= 0);
|
|
||||||
$minutes = abs($minutes);
|
|
||||||
$value1['hour'] = (int)$minutes / 60;
|
|
||||||
$value1['minute'] = $minutes % 60;
|
|
||||||
$minutes = $tbl_tz_row[2];
|
|
||||||
$value2['ahead'] = ($minutes > 0);
|
|
||||||
$minutes = abs($minutes);
|
|
||||||
$value2['hour'] = (int)$minutes / 60;
|
|
||||||
$value2['minute'] = $minutes % 60;
|
|
||||||
|
|
||||||
$daylight = Horde_iCalendar::newComponent('DAYLIGHT', $container);
|
|
||||||
$dtstart = $this->calc_dtstart($year, $tbl_tz_row[5],
|
|
||||||
$tbl_tz_row[6], $tbl_tz_row[7], $tbl_tz_row[8], $tbl_tz_row[9]);
|
|
||||||
$daylight->setAttribute('DTSTART', $dtstart);
|
|
||||||
$byday = ($tbl_tz_row[7] == 5 ? '-1' : $tbl_tz_row[7]) . $dayofweek[$tbl_tz_row[6]];
|
|
||||||
$rrule = array('FREQ' => 'YEARLY', 'BYMONTH' => $tbl_tz_row[5], 'BYDAY' => $byday);
|
|
||||||
if ($tbl_next_row)
|
|
||||||
{
|
|
||||||
$rrule['UNTIL'] = $tbl_next_row[4] . '0101T000000Z';
|
|
||||||
}
|
|
||||||
$daylight->setAttribute('RRULE', '', $rrule);
|
|
||||||
$daylight->setAttribute('TZNAME', $dstname);
|
|
||||||
$daylight->setAttribute('TZOFFSETFROM', $value2);
|
|
||||||
$daylight->setAttribute('TZOFFSETTO', $value1);
|
|
||||||
|
|
||||||
$standard = Horde_iCalendar::newComponent('STANDARD', $container);
|
|
||||||
$dtstart = $this->calc_dtstart($year, $tbl_tz_row[10], $tbl_tz_row[11],
|
|
||||||
$tbl_tz_row[12], $tbl_tz_row[13], $tbl_tz_row[14]);
|
|
||||||
$standard->setAttribute('DTSTART', $dtstart);
|
|
||||||
$byday = ($tbl_tz_row[12] == 5 ? '-1' : $tbl_tz_row[12]) . $dayofweek[$tbl_tz_row[11]];
|
|
||||||
$rrule['BYMONTH'] = $tbl_tz_row[10];
|
|
||||||
$rrule['BYDAY'] = $byday;
|
|
||||||
$standard->setAttribute('RRULE', '', $rrule);
|
|
||||||
$standard->setAttribute('TZNAME', $stdname);
|
|
||||||
$standard->setAttribute('TZOFFSETFROM', $value1);
|
|
||||||
$standard->setAttribute('TZOFFSETTO', $value2);
|
|
||||||
|
|
||||||
$vtimezone->addComponent($daylight);
|
|
||||||
$vtimezone->addComponent($standard);
|
|
||||||
if ($tbl_next_row)
|
|
||||||
{
|
|
||||||
$tbl_tz_row = $tbl_next_row;
|
|
||||||
$year = (int) $tbl_tz_row[4];
|
|
||||||
}
|
|
||||||
} while ($tbl_next_row && (empty($event['recur_enddate']) ||
|
|
||||||
$year <= date('Y', $event['recur_enddate'])));
|
|
||||||
|
|
||||||
$vcal->addComponent($vtimezone);
|
|
||||||
|
|
||||||
return $serverTZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* calculate the DTSTART value for a given timezone switch occurrence
|
|
||||||
*
|
|
||||||
* @param int $wYear
|
|
||||||
* @param int $wMonth
|
|
||||||
* @param int $wDayOfWeek
|
|
||||||
* @param int $wNth n-th day of week (5 last occurrence)
|
|
||||||
* @param int $wHour
|
|
||||||
* @param int $wMinute
|
|
||||||
* @return string DTSTART entry
|
|
||||||
*/
|
|
||||||
function calc_dtstart($wYear, $wMonth, $wDayOfWeek, $wNth, $wHour, $wMinute)
|
|
||||||
{
|
|
||||||
if (!$wYear) $wYear = 1981;
|
|
||||||
if ($wNth < 5)
|
|
||||||
{
|
|
||||||
$ts = mktime($wHour, $wMinute, 0, $wMonth, 1, $wYear);
|
|
||||||
$day = $wDayOfWeek - date('w', $ts);
|
|
||||||
if ($day < 0) $day += 7;
|
|
||||||
$day += 7 * ($wNth - 1) + 1;
|
|
||||||
$ts = mktime($wHour, $wMinute, 0, $wMonth, $day, $wYear);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$ts = mktime($wHour, $wMinute, 0, $wMonth, 31, $wYear);
|
|
||||||
$day = $wDayOfWeek - date('w', $ts);
|
|
||||||
if ($day > 0) $day -= 7;
|
|
||||||
$day += 31;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
$ts = mktime($wHour, $wMinute, 0, $wMonth, $day, $wYear);
|
|
||||||
$day -= 7;
|
|
||||||
} while ($wMonth < date('n', $ts));
|
|
||||||
}
|
|
||||||
$dtstart = date('Ymd\T', $ts) . sprintf("%'02u%'02u00", $wHour, $wMinute);
|
|
||||||
return $dtstart;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user