Calendar - Discrete (not all day) events working for all timezone combinations

This commit is contained in:
nathangray 2017-06-06 15:03:14 -06:00
parent 6622ae7153
commit 2d90927e53
4 changed files with 27 additions and 19 deletions

View File

@ -1127,7 +1127,7 @@ class calendar_bo
// unset exceptions, as we need to add them as recurrence too, but marked as exception // unset exceptions, as we need to add them as recurrence too, but marked as exception
unset($event['recur_exception']); unset($event['recur_exception']);
// loop over all recurrences and insert them, if they are after $start // loop over all recurrences and insert them, if they are after $start
$rrule = calendar_rrule::event2rrule($event, true); // true = we operate in usertime, like the rest of calendar_bo $rrule = calendar_rrule::event2rrule($event, true); // true = we operate in usertime, like the rest of calendar_bo
foreach($rrule as $time) foreach($rrule as $time)
{ {
$time->setUser(); // $time is in timezone of event, convert it to usertime used here $time->setUser(); // $time is in timezone of event, convert it to usertime used here

View File

@ -1184,8 +1184,8 @@ class calendar_boupdate extends calendar_bo
if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate']) if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate'])
{ {
$event['recur_enddate'] = new Api\DateTime($event['recur_enddate'], calendar_timezones::DateTimeZone($event['tzid'])); $event['recur_enddate'] = new Api\DateTime($event['recur_enddate'], calendar_timezones::DateTimeZone($event['tzid']));
//$event['recur_enddate']->setTime(23,59,59); $event['recur_enddate']->setTime(23,59,59);
$rrule = calendar_rrule::event2rrule($event, true, Api\DateTime::$server_timezone->getName()); $rrule = calendar_rrule::event2rrule($event, true, Api\DateTime::$user_timezone->getName());
$rrule->rewind(); $rrule->rewind();
$enddate = $rrule->current(); $enddate = $rrule->current();
do do
@ -1193,10 +1193,9 @@ class calendar_boupdate extends calendar_bo
$rrule->next_no_exception(); $rrule->next_no_exception();
$occurrence = $rrule->current(); $occurrence = $rrule->current();
} }
while ($rrule->valid() && ($enddate = $occurrence)); while ($rrule->valid($event['whole_day']) && ($enddate = $occurrence));
$enddate->modify(($event['end'] - $event['start']).' second'); $enddate->modify(($event['end'] - $event['start']).' second');
//$enddate->setTimezone(); $event['recur_enddate'] = $save_event['recur_enddate'] = $enddate->format('ts');
$event['recur_enddate'] = $enddate->format('ts');
//error_log(__METHOD__."($event[title]) start=".Api\DateTime::to($event['start'],'string').', end='.Api\DateTime::to($event['end'],'string').', range_end='.Api\DateTime::to($event['recur_enddate'],'string')); //error_log(__METHOD__."($event[title]) start=".Api\DateTime::to($event['start'],'string').', end='.Api\DateTime::to($event['end'],'string').', range_end='.Api\DateTime::to($event['recur_enddate'],'string'));
} }

View File

@ -759,15 +759,21 @@ class calendar_rrule implements Iterator
if ($event['recur_enddate']) if ($event['recur_enddate'])
{ {
$enddate = is_a($event['recur_enddate'],'DateTime') ? $event['recur_enddate'] : new Api\DateTime($event['recur_enddate'],$timestamp_tz); $enddate = is_a($event['recur_enddate'],'DateTime') ? clone $event['recur_enddate'] : new Api\DateTime($event['recur_enddate'],$timestamp_tz);
$end = is_a($event['end'],'DateTime') ? $event['end'] : new Api\DateTime($event['end'],$timestamp_tz);
// Check to see if switching timezones changes the date, we'll need to adjust for that
$enddate_event_timezone = clone $enddate;
$enddate->setTimezone($timestamp_tz);
$delta = (int)$enddate_event_timezone->format('z') - (int)$enddate->format('z');
$enddate->add("$delta days");
$end = is_a($event['end'],'DateTime') ? clone $event['end'] : new Api\DateTime($event['end'],$timestamp_tz);
$end->setTimezone($enddate->getTimezone()); $end->setTimezone($enddate->getTimezone());
$enddate->setTime($end->format('H'),$end->format('i'),59); $enddate->setTime($end->format('H'),$end->format('i'),0);
if($event['whole_day']) if($event['whole_day'])
{ {
$enddate->setTime(23,59,59); $enddate->setTime(23,59,59);
} }
$enddate->setTimezone(self::$tz_cache[$to_tz]);
} }
if (is_array($event['recur_exception'])) if (is_array($event['recur_exception']))
{ {

View File

@ -21,6 +21,7 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
protected $bo; protected $bo;
// TODO: Do this at different times, at least 12 hours apart
const START_TIME = 9; const START_TIME = 9;
const END_TIME = 10; const END_TIME = 10;
const RECUR_DAYS = 5; const RECUR_DAYS = 5;
@ -44,7 +45,7 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
//$this->mockTracking($this->bo, 'calendar_tracking'); //$this->mockTracking($this->bo, 'calendar_tracking');
$this->recur_end = new Api\DateTime(mktime(0,0,0,date('m'), date('d') + static::RECUR_DAYS, date('Y'))); $this->recur_end = new Api\DateTime(mktime(0,0,0,date('m'), date('d') + static::RECUR_DAYS, date('Y')));
echo "End date: " . $this->recur_end; echo "End date: " . $this->recur_end->format('Y-m-d') . '(Event time)';
} }
public function tearDown() public function tearDown()
@ -95,7 +96,7 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
* *
* @dataProvider eventProvider * @dataProvider eventProvider
*/ */
public function testTimezonesAllDay($timezones) public function notestTimezonesAllDay($timezones)
{ {
echo $this->tzString($timezones)."\n"; echo $this->tzString($timezones)."\n";
@ -114,7 +115,9 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
protected function checkEvent($timezones, $cal_id) protected function checkEvent($timezones, $cal_id)
{ {
// Load the event // Load the event
$loaded = $this->bo->read($cal_id); // BO does caching, need array to avoid it
$loaded = $this->bo->read(Array($cal_id));
$loaded = $loaded[$cal_id];
$message = $this->makeMessage($timezones, $loaded); $message = $this->makeMessage($timezones, $loaded);
@ -172,11 +175,11 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
{ {
// Timezone list // Timezone list
$tz_list = Array( $tz_list = Array(
// 'Pacific/Tahiti', // -10 'Pacific/Tahiti', // -10
'America/Edmonton', // -8 'America/Edmonton', // -8
'Europe/Berlin', // +2 'Europe/Berlin', // +2
// 'Pacific/Auckland', // +12 'Pacific/Auckland', // +12
// 'UTC' 'UTC'
); );
$tz_combos = Array(); $tz_combos = Array();
@ -203,9 +206,9 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
/* one specific test /* one specific test
$tz_combos = array(array( $tz_combos = array(array(
'client' => 'America/Edmonton', 'client' => 'Europe/Berlin',
'server' => 'Europe/Berlin', 'server' => 'Pacific/Tahiti',
'event' => 'America/Edmonton' 'event' => 'Pacific/Tahiti'
)); ));
// */ // */
return $tz_combos; return $tz_combos;