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'));
|
||||
|
||||
// set user's timezone
|
||||
$this->timezone = $this->rc->config->get_timezone();
|
||||
$this->gmt_offset = $this->timezone * 3600;
|
||||
$this->timezone = $this->rc->config->get('timezone');
|
||||
$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');
|
||||
$this->ui = new calendar_ui($this);
|
||||
|
@ -589,11 +591,13 @@ class calendar extends rcube_plugin
|
|||
break;
|
||||
|
||||
case "resize":
|
||||
$this->prepare_event($event, $action);
|
||||
$success = $this->driver->resize_event($event);
|
||||
$reload = $event['_savemode'] ? 2 : 1;
|
||||
break;
|
||||
|
||||
case "move":
|
||||
$this->prepare_event($event, $action);
|
||||
$success = $this->driver->move_event($event);
|
||||
$reload = $success && $event['_savemode'] ? 2 : 1;
|
||||
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['event_coloring'] = (int)$this->rc->config->get('calendar_event_coloring', $this->defaults['calendar_event_coloring']);
|
||||
$settings['timezone'] = $this->timezone;
|
||||
$settings['dst'] = $this->dst_active;
|
||||
|
||||
// localization
|
||||
$settings['days'] = array(
|
||||
|
@ -934,6 +939,19 @@ class calendar extends rcube_plugin
|
|||
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
|
||||
*
|
||||
|
@ -1447,9 +1465,11 @@ class calendar extends rcube_plugin
|
|||
*/
|
||||
private function prepare_event(&$event, $action)
|
||||
{
|
||||
$eventid = 'cal:'.$event['id'];
|
||||
$event['start'] = $this->fixDST($event['start']);
|
||||
$event['end'] = $this->fixDST($event['end']);
|
||||
|
||||
$attachments = array();
|
||||
$eventid = 'cal:'.$event['id'];
|
||||
if (is_array($_SESSION['event_session']) && $_SESSION['event_session']['id'] == $eventid) {
|
||||
if (!empty($_SESSION['event_session']['attachments'])) {
|
||||
foreach ($_SESSION['event_session']['attachments'] as $id => $attachment) {
|
||||
|
@ -1463,7 +1483,7 @@ class calendar extends rcube_plugin
|
|||
$event['attachments'] = $attachments;
|
||||
|
||||
// check for organizer in attendees
|
||||
if ($event['attendees']) {
|
||||
if ($event['attendees'] && ($action == 'new' || $action == 'edit')) {
|
||||
$emails = $this->get_user_emails();
|
||||
$organizer = $owner = false;
|
||||
foreach ($event['attendees'] as $i => $attendee) {
|
||||
|
@ -1571,7 +1591,7 @@ class calendar extends rcube_plugin
|
|||
}
|
||||
|
||||
// add timezone information
|
||||
if ($tzinfo && ($tzname = timezone_name_from_abbr("", $this->gmt_offset, 0))) {
|
||||
if ($tzinfo && ($tzname = $this->user_timezone->getName())) {
|
||||
$fromto .= ' (' . $tzname . ')';
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ function rcube_calendar_ui(settings)
|
|||
var DAY_MS = 86400000;
|
||||
var HOUR_MS = 3600000;
|
||||
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 ignore_click = false;
|
||||
var event_defaults = { free_busy:'busy' };
|
||||
|
@ -2272,6 +2272,12 @@ function rcube_calendar_ui(settings)
|
|||
},
|
||||
// callback for event resizing
|
||||
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
|
||||
var data = {
|
||||
id: event.id,
|
||||
|
|
|
@ -447,7 +447,7 @@ class kolab_calendar
|
|||
|
||||
$events = array();
|
||||
$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
|
||||
$dst_start = $next->format('I');
|
||||
$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
|
||||
$rec['start-date'] += 12 * 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['start-date'] -= $this->cal->timezone * 3600 - date('Z', $rec['start-date']); // because generated with mktime() in Horde_Kolab_Format_Date::decodeDate()
|
||||
$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->gmt_offset - date('Z', $rec['start-date']); // because generated with mktime() in Horde_Kolab_Format_Date::decodeDate()
|
||||
// sanity check
|
||||
if ($rec['end-date'] <= $rec['start-date'])
|
||||
$rec['end-date'] += 86400;
|
||||
|
@ -623,7 +623,7 @@ class kolab_calendar
|
|||
private function _from_rcube_event($event)
|
||||
{
|
||||
$priority_map = $this->priority_map;
|
||||
$tz_offset = $this->cal->timezone * 3600;
|
||||
$tz_offset = $this->cal->gmt_offset;
|
||||
|
||||
$object = array(
|
||||
// kolab => roundcube
|
||||
|
|
|
@ -52,7 +52,7 @@ class calendar_ical
|
|||
|
||||
// compose timezone string
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -104,12 +104,12 @@ class calendar_ical
|
|||
|
||||
// check for all-day dates
|
||||
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['allday'] = true;
|
||||
}
|
||||
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
|
||||
|
@ -221,8 +221,8 @@ class calendar_ical
|
|||
*/
|
||||
private function _date2time($prop)
|
||||
{
|
||||
// create timestamp at 00:00 in user's timezone
|
||||
return is_array($prop) ? strtotime(sprintf('%04d%02d%02dT000000%s', $prop['year'], $prop['month'], $prop['mday'], $this->timezone)) : $prop;
|
||||
// create timestamp at 12:00 in user's timezone
|
||||
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
|
||||
if ($event['allday']) {
|
||||
$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 {
|
||||
$vevent .= "DTSTART:" . gmdate('Ymd\THis\Z', $event['start']) . self::EOL;
|
||||
|
|
Loading…
Add table
Reference in a new issue