Fixed DST issues but still working with timestamps because Kolab_Format does
This commit is contained in:
parent
5c054b1094
commit
154d25b5b9
4 changed files with 42 additions and 16 deletions
|
@ -96,8 +96,10 @@ class calendar extends rcube_plugin
|
||||||
$this->add_texts('localization/', $this->rc->task == 'calendar' && (!$this->rc->action || $this->rc->action == 'print'));
|
$this->add_texts('localization/', $this->rc->task == 'calendar' && (!$this->rc->action || $this->rc->action == 'print'));
|
||||||
|
|
||||||
// set user's timezone
|
// set user's timezone
|
||||||
$this->timezone = $this->rc->config->get_timezone();
|
$this->timezone = $this->rc->config->get('timezone');
|
||||||
$this->gmt_offset = $this->timezone * 3600;
|
$this->dst_active = $this->rc->config->get('dst_active');
|
||||||
|
$this->gmt_offset = ($this->timezone + $this->dst_active) * 3600;
|
||||||
|
$this->user_timezone = new DateTimeZone($this->timezone ? timezone_name_from_abbr("", $this->gmt_offset, $this->dst_active) : 'GMT');
|
||||||
|
|
||||||
require($this->home . '/lib/calendar_ui.php');
|
require($this->home . '/lib/calendar_ui.php');
|
||||||
$this->ui = new calendar_ui($this);
|
$this->ui = new calendar_ui($this);
|
||||||
|
@ -589,11 +591,13 @@ class calendar extends rcube_plugin
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "resize":
|
case "resize":
|
||||||
|
$this->prepare_event($event, $action);
|
||||||
$success = $this->driver->resize_event($event);
|
$success = $this->driver->resize_event($event);
|
||||||
$reload = $event['_savemode'] ? 2 : 1;
|
$reload = $event['_savemode'] ? 2 : 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "move":
|
case "move":
|
||||||
|
$this->prepare_event($event, $action);
|
||||||
$success = $this->driver->move_event($event);
|
$success = $this->driver->move_event($event);
|
||||||
$reload = $success && $event['_savemode'] ? 2 : 1;
|
$reload = $success && $event['_savemode'] ? 2 : 1;
|
||||||
break;
|
break;
|
||||||
|
@ -850,6 +854,7 @@ class calendar extends rcube_plugin
|
||||||
$settings['agenda_sections'] = $this->rc->config->get('calendar_agenda_sections', $this->defaults['calendar_agenda_sections']);
|
$settings['agenda_sections'] = $this->rc->config->get('calendar_agenda_sections', $this->defaults['calendar_agenda_sections']);
|
||||||
$settings['event_coloring'] = (int)$this->rc->config->get('calendar_event_coloring', $this->defaults['calendar_event_coloring']);
|
$settings['event_coloring'] = (int)$this->rc->config->get('calendar_event_coloring', $this->defaults['calendar_event_coloring']);
|
||||||
$settings['timezone'] = $this->timezone;
|
$settings['timezone'] = $this->timezone;
|
||||||
|
$settings['dst'] = $this->dst_active;
|
||||||
|
|
||||||
// localization
|
// localization
|
||||||
$settings['days'] = array(
|
$settings['days'] = array(
|
||||||
|
@ -934,6 +939,19 @@ class calendar extends rcube_plugin
|
||||||
return $ts + $this->gmt_offset;
|
return $ts + $this->gmt_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix DST difference between client and target date
|
||||||
|
*/
|
||||||
|
function fixDST($time)
|
||||||
|
{
|
||||||
|
$date = new DateTime(null, $this->user_timezone);
|
||||||
|
$date->setTimeStamp($time);
|
||||||
|
$diff = $date->format('I') - $this->dst_active;
|
||||||
|
$time += $diff * 3600;
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode events as JSON
|
* Encode events as JSON
|
||||||
*
|
*
|
||||||
|
@ -1447,9 +1465,11 @@ class calendar extends rcube_plugin
|
||||||
*/
|
*/
|
||||||
private function prepare_event(&$event, $action)
|
private function prepare_event(&$event, $action)
|
||||||
{
|
{
|
||||||
$eventid = 'cal:'.$event['id'];
|
$event['start'] = $this->fixDST($event['start']);
|
||||||
|
$event['end'] = $this->fixDST($event['end']);
|
||||||
|
|
||||||
$attachments = array();
|
$attachments = array();
|
||||||
|
$eventid = 'cal:'.$event['id'];
|
||||||
if (is_array($_SESSION['event_session']) && $_SESSION['event_session']['id'] == $eventid) {
|
if (is_array($_SESSION['event_session']) && $_SESSION['event_session']['id'] == $eventid) {
|
||||||
if (!empty($_SESSION['event_session']['attachments'])) {
|
if (!empty($_SESSION['event_session']['attachments'])) {
|
||||||
foreach ($_SESSION['event_session']['attachments'] as $id => $attachment) {
|
foreach ($_SESSION['event_session']['attachments'] as $id => $attachment) {
|
||||||
|
@ -1463,7 +1483,7 @@ class calendar extends rcube_plugin
|
||||||
$event['attachments'] = $attachments;
|
$event['attachments'] = $attachments;
|
||||||
|
|
||||||
// check for organizer in attendees
|
// check for organizer in attendees
|
||||||
if ($event['attendees']) {
|
if ($event['attendees'] && ($action == 'new' || $action == 'edit')) {
|
||||||
$emails = $this->get_user_emails();
|
$emails = $this->get_user_emails();
|
||||||
$organizer = $owner = false;
|
$organizer = $owner = false;
|
||||||
foreach ($event['attendees'] as $i => $attendee) {
|
foreach ($event['attendees'] as $i => $attendee) {
|
||||||
|
@ -1571,7 +1591,7 @@ class calendar extends rcube_plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// add timezone information
|
// add timezone information
|
||||||
if ($tzinfo && ($tzname = timezone_name_from_abbr("", $this->gmt_offset, 0))) {
|
if ($tzinfo && ($tzname = $this->user_timezone->getName())) {
|
||||||
$fromto .= ' (' . $tzname . ')';
|
$fromto .= ' (' . $tzname . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ function rcube_calendar_ui(settings)
|
||||||
var DAY_MS = 86400000;
|
var DAY_MS = 86400000;
|
||||||
var HOUR_MS = 3600000;
|
var HOUR_MS = 3600000;
|
||||||
var me = this;
|
var me = this;
|
||||||
var gmt_offset = (new Date().getTimezoneOffset() / -60) - (settings.timezone || 0);
|
var gmt_offset = (new Date().getTimezoneOffset() / -60) - (settings.timezone || 0) - (settings.dst || 0);
|
||||||
var day_clicked = day_clicked_ts = 0;
|
var day_clicked = day_clicked_ts = 0;
|
||||||
var ignore_click = false;
|
var ignore_click = false;
|
||||||
var event_defaults = { free_busy:'busy' };
|
var event_defaults = { free_busy:'busy' };
|
||||||
|
@ -2272,6 +2272,12 @@ function rcube_calendar_ui(settings)
|
||||||
},
|
},
|
||||||
// callback for event resizing
|
// callback for event resizing
|
||||||
eventResize: function(event, delta) {
|
eventResize: function(event, delta) {
|
||||||
|
// sanitize event dates
|
||||||
|
if (event.allDay)
|
||||||
|
event.start.setHours(12);
|
||||||
|
if (!event.end || event.end.getTime() < event.start.getTime())
|
||||||
|
event.end = new Date(event.start.getTime() + HOUR_MS);
|
||||||
|
|
||||||
// send resize request to server
|
// send resize request to server
|
||||||
var data = {
|
var data = {
|
||||||
id: event.id,
|
id: event.id,
|
||||||
|
|
|
@ -447,7 +447,7 @@ class kolab_calendar
|
||||||
|
|
||||||
$events = array();
|
$events = array();
|
||||||
$duration = $event['end'] - $event['start'];
|
$duration = $event['end'] - $event['start'];
|
||||||
$tz_offset = $event['allday'] ? $this->cal->timezone * 3600 - date('Z') : 0;
|
$tz_offset = $event['allday'] ? $this->cal->gmt_offset - date('Z') : 0;
|
||||||
$next = new Horde_Date($event['start'] + $tz_offset); # shift all-day times to server timezone because computation operates in local TZ
|
$next = new Horde_Date($event['start'] + $tz_offset); # shift all-day times to server timezone because computation operates in local TZ
|
||||||
$dst_start = $next->format('I');
|
$dst_start = $next->format('I');
|
||||||
$hour = $next->hour;
|
$hour = $next->hour;
|
||||||
|
@ -494,8 +494,8 @@ class kolab_calendar
|
||||||
if ($allday) { // in Roundcube all-day events only go from 12:00 to 13:00
|
if ($allday) { // in Roundcube all-day events only go from 12:00 to 13:00
|
||||||
$rec['start-date'] += 12 * 3600;
|
$rec['start-date'] += 12 * 3600;
|
||||||
$rec['end-date'] -= 11 * 3600;
|
$rec['end-date'] -= 11 * 3600;
|
||||||
$rec['end-date'] -= $this->cal->timezone * 3600 - date('Z', $rec['end-date']); // shift 00 times from server's timezone to user's timezone
|
$rec['end-date'] -= $this->cal->gmt_offset - date('Z', $rec['end-date']); // shift times from server's timezone to user's timezone
|
||||||
$rec['start-date'] -= $this->cal->timezone * 3600 - date('Z', $rec['start-date']); // because generated with mktime() in Horde_Kolab_Format_Date::decodeDate()
|
$rec['start-date'] -= $this->cal->gmt_offset - date('Z', $rec['start-date']); // because generated with mktime() in Horde_Kolab_Format_Date::decodeDate()
|
||||||
// sanity check
|
// sanity check
|
||||||
if ($rec['end-date'] <= $rec['start-date'])
|
if ($rec['end-date'] <= $rec['start-date'])
|
||||||
$rec['end-date'] += 86400;
|
$rec['end-date'] += 86400;
|
||||||
|
@ -623,7 +623,7 @@ class kolab_calendar
|
||||||
private function _from_rcube_event($event)
|
private function _from_rcube_event($event)
|
||||||
{
|
{
|
||||||
$priority_map = $this->priority_map;
|
$priority_map = $this->priority_map;
|
||||||
$tz_offset = $this->cal->timezone * 3600;
|
$tz_offset = $this->cal->gmt_offset;
|
||||||
|
|
||||||
$object = array(
|
$object = array(
|
||||||
// kolab => roundcube
|
// kolab => roundcube
|
||||||
|
|
|
@ -52,7 +52,7 @@ class calendar_ical
|
||||||
|
|
||||||
// compose timezone string
|
// compose timezone string
|
||||||
if ($cal->timezone) {
|
if ($cal->timezone) {
|
||||||
$hours = floor($cal->timezone);
|
$hours = floor($cal->timezone + $cal->dst_active);
|
||||||
$this->timezone = sprintf('%s%02d:%02d', ($hours >= 0 ? '+' : ''), $hours, ($cal->timezone - $hours) * 60);
|
$this->timezone = sprintf('%s%02d:%02d', ($hours >= 0 ? '+' : ''), $hours, ($cal->timezone - $hours) * 60);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,12 +104,12 @@ class calendar_ical
|
||||||
|
|
||||||
// check for all-day dates
|
// check for all-day dates
|
||||||
if (is_array($event['start'])) {
|
if (is_array($event['start'])) {
|
||||||
// create timestamp at 00:00 in user's timezone
|
// create timestamp at 12:00 in user's timezone
|
||||||
$event['start'] = $this->_date2time($event['start']);
|
$event['start'] = $this->_date2time($event['start']);
|
||||||
$event['allday'] = true;
|
$event['allday'] = true;
|
||||||
}
|
}
|
||||||
if (is_array($event['end'])) {
|
if (is_array($event['end'])) {
|
||||||
$event['end'] = $this->_date2time($event['end']) - 60;
|
$event['end'] = $this->_date2time($event['end']) - 23 * 3600;
|
||||||
}
|
}
|
||||||
|
|
||||||
// map other attributes to internal fields
|
// map other attributes to internal fields
|
||||||
|
@ -221,8 +221,8 @@ class calendar_ical
|
||||||
*/
|
*/
|
||||||
private function _date2time($prop)
|
private function _date2time($prop)
|
||||||
{
|
{
|
||||||
// create timestamp at 00:00 in user's timezone
|
// create timestamp at 12:00 in user's timezone
|
||||||
return is_array($prop) ? strtotime(sprintf('%04d%02d%02dT000000%s', $prop['year'], $prop['month'], $prop['mday'], $this->timezone)) : $prop;
|
return is_array($prop) ? strtotime(sprintf('%04d%02d%02dT120000%s', $prop['year'], $prop['month'], $prop['mday'], $this->timezone)) : $prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ class calendar_ical
|
||||||
// correctly set all-day dates
|
// correctly set all-day dates
|
||||||
if ($event['allday']) {
|
if ($event['allday']) {
|
||||||
$vevent .= "DTSTART;VALUE=DATE:" . gmdate('Ymd', $event['start'] + $this->cal->gmt_offset) . self::EOL;
|
$vevent .= "DTSTART;VALUE=DATE:" . gmdate('Ymd', $event['start'] + $this->cal->gmt_offset) . self::EOL;
|
||||||
$vevent .= "DTEND;VALUE=DATE:" . gmdate('Ymd', $event['end'] + $this->cal->gmt_offset + 60) . self::EOL; // ends the next day
|
$vevent .= "DTEND;VALUE=DATE:" . gmdate('Ymd', $event['end'] + $this->cal->gmt_offset + 86400) . self::EOL; // ends the next day
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$vevent .= "DTSTART:" . gmdate('Ymd\THis\Z', $event['start']) . self::EOL;
|
$vevent .= "DTSTART:" . gmdate('Ymd\THis\Z', $event['start']) . self::EOL;
|
||||||
|
|
Loading…
Add table
Reference in a new issue