Fix timezone problems when importing all-day events (#284)

This commit is contained in:
Thomas Bruederli 2011-08-06 16:12:34 +02:00
parent 94bff75de6
commit f85d386c39
3 changed files with 18 additions and 14 deletions

View file

@ -1369,8 +1369,9 @@ class calendar extends rcube_plugin
$time_format = self::to_php_date_format($this->rc->config->get('calendar_time_format', $this->defaults['calendar_time_format'])); $time_format = self::to_php_date_format($this->rc->config->get('calendar_time_format', $this->defaults['calendar_time_format']));
if ($event['allday']) { if ($event['allday']) {
$fromto = format_date($event['start'], $date_format) . $fromto = format_date($event['start'], $date_format);
($duration > 86400 || gmdate('d', $event['start']) != gmdate('d', $event['end']) ? ' - ' . format_date($event['end'], $date_format) : ''); if (($todate = format_date($event['end'], $date_format)) != $fromto)
$fromto .= ' - ' . $todate;
} }
else if ($duration < 86400 && gmdate('d', $event['start']) == gmdate('d', $event['end'])) { else if ($duration < 86400 && gmdate('d', $event['start']) == gmdate('d', $event['end'])) {
$fromto = format_date($event['start'], $date_format) . ' ' . format_date($event['start'], $time_format) . $fromto = format_date($event['start'], $date_format) . ' ' . format_date($event['start'], $time_format) .
@ -1554,8 +1555,7 @@ class calendar extends rcube_plugin
{ {
// load iCalendar functions (if necessary) // load iCalendar functions (if necessary)
if (!empty($this->ics_parts)) { if (!empty($this->ics_parts)) {
require($this->home . '/lib/calendar_ical.php'); $this->load_ical();
$this->ical = new calendar_ical($this->rc);
} }
$html = ''; $html = '';
@ -1617,7 +1617,7 @@ class calendar extends rcube_plugin
$this->load_ical(); $this->load_ical();
$events = $this->ical->import($part, $charset); $events = $this->ical->import($part, $charset);
$error_msg = $this->gettext('errorimportingevent'); $error_msg = $this->gettext('errorimportingevent');
$success = false; $success = false;

View file

@ -344,10 +344,6 @@ class database_driver extends calendar_driver
$event['free_busy'] = intval($this->free_busy_map[strtolower($event['free_busy'])]); $event['free_busy'] = intval($this->free_busy_map[strtolower($event['free_busy'])]);
if (isset($event['allday'])) { if (isset($event['allday'])) {
// set times to 00::00 and 23:59 (assuming the PHP and DB timezones are in sync)
$numdays = max(1, round(($event['end'] - $event['start']) / 86400));
$event['start'] = mktime(0, 0, 0, date('n', $event['start']), date('j', $event['start']), date('Y', $event['start']));
$event['end'] = $event['start'] + $numdays * 86400 - 60;
$event['all_day'] = $event['allday'] ? 1 : 0; $event['all_day'] = $event['allday'] ? 1 : 0;
} }
@ -620,6 +616,7 @@ class database_driver extends calendar_driver
public function get_event($event) public function get_event($event)
{ {
$id = is_array($event) ? $event['id'] : $event; $id = is_array($event) ? $event['id'] : $event;
$col = is_numeric($event['id']) ? 'event_id' : 'uid';
if ($this->cache[$id]) if ($this->cache[$id])
return $this->cache[$id]; return $this->cache[$id];
@ -627,7 +624,7 @@ class database_driver extends calendar_driver
$result = $this->rc->db->query(sprintf( $result = $this->rc->db->query(sprintf(
"SELECT * FROM " . $this->db_events . " "SELECT * FROM " . $this->db_events . "
WHERE calendar_id IN (%s) WHERE calendar_id IN (%s)
AND event_id=?", AND $col=?",
$this->calendar_ids $this->calendar_ids
), ),
$id); $id);

View file

@ -39,12 +39,18 @@ class calendar_ical
private $rc; private $rc;
private $cal; private $cal;
private $timezone = 'Z';
function __construct($cal) function __construct($cal)
{ {
$this->cal = $cal; $this->cal = $cal;
$this->rc = $cal->rc; $this->rc = $cal->rc;
// compose timezone string
if ($cal->timezone) {
$hours = floor($cal->timezone);
$this->timezone = sprintf('%s%02d:%02d', ($hours >= 0 ? '+' : ''), $hours, ($cal->timezone - $hours) * 60);
}
} }
/** /**
@ -93,13 +99,14 @@ class calendar_ical
// check for all-day dates // check for all-day dates
if (is_array($event['start'])) { if (is_array($event['start'])) {
$event['start'] = gmmktime(0, 0, 0, $event['start']['month'], $event['start']['mday'], $event['start']['year']) + $this->cal->gmt_offset; // create timestamp at 00:00 in user's timezone
$event['start'] = strtotime(sprintf('%04d%02d%02dT000000%s', $event['start']['year'], $event['start']['month'], $event['start']['mday'], $this->timezone));
$event['allday'] = true; $event['allday'] = true;
} }
if (is_array($event['end'])) { if (is_array($event['end'])) {
$event['end'] = gmmktime(0, 0, 0, $event['end']['month'], $event['end']['mday'], $event['end']['year']) + $this->cal->gmt_offset - 60; $event['end'] = strtotime(sprintf('%04d%02d%02dT000000%s', $event['end']['year'], $event['end']['month'], $event['end']['mday'], $this->timezone)) - 60;
} }
// map other attributes to internal fields // map other attributes to internal fields
$_attendees = array(); $_attendees = array();
foreach ($ve->getAllAttributes() as $attr) { foreach ($ve->getAllAttributes() as $attr) {