From 0afaeadb159fff7da91250d099be7952de57b9f8 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Sat, 14 Dec 2013 22:38:33 -0500 Subject: [PATCH] CC-5641: Can Create Zero or Negative Length Shows * Fixed two underlying causes of zero or negative length shows that could be created over DST time changes: - Fixed incorrect end time arithmetic which did not preserve the show duration. - Fixed a desynchronization issue due to FullCalendar handling events over DST differently from Airtime. --- .../application/services/CalendarService.php | 21 +++++++++++++++++-- .../schedule/full-calendar-functions.js | 6 ++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/services/CalendarService.php b/airtime_mvc/application/services/CalendarService.php index 4ba92e3bb..a2d690490 100644 --- a/airtime_mvc/application/services/CalendarService.php +++ b/airtime_mvc/application/services/CalendarService.php @@ -270,9 +270,26 @@ class Application_Service_CalendarService $startsDateTime->setTimezone(new DateTimeZone($showTimezone)); $endsDateTime->setTimezone(new DateTimeZone($showTimezone)); + $duration = $startsDateTime->diff($endsDateTime); + $newStartsDateTime = self::addDeltas($startsDateTime, $deltaDay, $deltaMin); - $newEndsDateTime = self::addDeltas($endsDateTime, $deltaDay, $deltaMin); - + /* WARNING: Do not separately add a time delta to the start and end times because + that does not preserve the duration across a DST time change. + For example, 5am - 3 hours = 3am when DST occurs at 2am. + BUT, 6am - 3 hours = 3am also! + So when a DST change occurs, adding the deltas like this + separately does not conserve the duration of a show. + Since that's what we want (otherwise we'll get a zero length show), + we calculate the show duration FIRST, then we just add that on + to the start time to calculate the end time. + This is a safer approach. + The key lesson here is that in general: duration != end - start + ... so be careful! + */ + //$newEndsDateTime = self::addDeltas($endsDateTime, $deltaDay, $deltaMin); <--- Wrong, don't do it. + $newEndsDateTime = clone $newStartsDateTime; + $newEndsDateTime = $newEndsDateTime->add($duration); + //convert our new starts/ends to UTC. $newStartsDateTime->setTimezone(new DateTimeZone("UTC")); $newEndsDateTime->setTimezone(new DateTimeZone("UTC")); diff --git a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js index e90f2ee68..a178159ca 100644 --- a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js +++ b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js @@ -325,6 +325,12 @@ function eventDrop(event, dayDelta, minuteDelta, allDay, revertFunc, jsEvent, ui alert(json.error); revertFunc(); } + + //Workaround for cases where FullCalendar handles events over DST + //time changes in a different way than Airtime does. + //(Airtime preserves show duration, FullCalendar doesn't.) + scheduleRefetchEvents(json); + }); }