diff options
author | Anton Schubert | 2020-10-31 20:43:09 +0100 |
---|---|---|
committer | GitHub | 2020-10-31 20:43:09 +0100 |
commit | c31a16cb6d9057883cc5f46376c190a8a8736546 (patch) | |
tree | dfe4bd1853fffd259f01a2ad920f6ae00cb44bb8 /model | |
parent | 84b8eb8048fcdb8e6449583583aa21b7bb90486e (diff) |
preserve schedule timezones and show current time + event timezone on the website (#117)
Diffstat (limited to 'model')
-rw-r--r-- | model/Schedule.php | 195 |
1 files changed, 90 insertions, 105 deletions
diff --git a/model/Schedule.php b/model/Schedule.php index d006d1f..739d2c8 100644 --- a/model/Schedule.php +++ b/model/Schedule.php @@ -89,31 +89,32 @@ class Schedule // so to be on the safer side we calculate our own daystart/end here foreach($schedule->day as $day) { - $daystart = PHP_INT_MAX; - $dayend = 0; + $daystart = new DateTimeImmutable('+100 year'); + $dayend = new DateTimeImmutable('-100 year'); foreach($day->room as $room) { $roomName = (string)$room['name']; if($this->isRoomFiltered($roomName)) continue; - + if(!in_array($roomName, $rooms)) $rooms[] = $roomName; foreach($room->event as $event) { - $start = strtotime((string)$event->date); - $duration = $this->strToDuration((string)$event->duration); - $end = $start + $duration; + $start = new DateTimeImmutable((string)$event->date); + $interval = $this->strToInterval((string)$event->duration); + $end = $start->add($interval); - $daystart = min($daystart, $start); - $dayend = max($dayend, $end); + $daystart = $start < $daystart ? $start : $daystart; + $dayend = $end > $dayend ? $end : $dayend; } } - $day['start'] = $daystart; - $day['end'] = $dayend; + // stringify again to store in simplexml + $day['start'] = $daystart->format('c'); + $day['end'] = $dayend->format('c'); } @@ -123,23 +124,23 @@ class Schedule $daysSorted[] = $day; } - usort($daysSorted, function($a, $b) { - return (int)$a['start'] - (int)$b['start']; + usort($daysSorted, function($a, $b): int { + return strcmp($a['start'], $b['start']); }); $dayidx = 0; foreach($daysSorted as $day) { $dayidx++; - $daystart = (int)$day['start']; - $dayend = (int)$day['end']; + $daystart = new DateTimeImmutable($day['start']); + $dayend = new DateTimeImmutable($day['end']); $roomidx = 0; foreach($rooms as $roomName) { $roomidx++; - $laststart = false; - $lastend = false; + $laststart = NULL; + $lastend = NULL; if($this->isRoomFiltered($roomName)) continue; @@ -147,24 +148,16 @@ class Schedule $result = $day->xpath("room[@name='".$roomName."']"); if(!$result) { // this room has no events on this day -> add long gap - $program[$roomName][] = array( - 'special' => 'gap', - - 'fstart' => date('c', $daystart), - 'fend' => date('c', $dayend), - - 'start' => $daystart, - 'end' => $dayend, - 'duration' => $dayend - $daystart, - ); - $program[$roomName][] = array( - 'special' => 'daychange', - 'title' => 'Daychange from Day '.$dayidx.' to '.($dayidx+1), - - 'start' => $dayend, - 'end' => (int)$schedule->day[$dayidx]['start'], - 'duration' => 60*60, - ); + $gap = $this->makeEvent($daystart, $dayend); + $gap['special'] = 'gap'; + $program[$roomName][] = $gap; + + $end = new DateTimeImmutable($schedule->day[$dayidx]['start']); + $daychange = $this->makeEvent($dayend, $end); + $daychange['special'] = 'daychange'; + $daychange['title'] = 'Daychange from Day '.$dayidx.' to '.($dayidx+1); + $daychange['duration'] = 3600; + $program[$roomName][] = $daychange; continue; } $room = $result[0]; @@ -184,103 +177,74 @@ class Schedule foreach($eventsSorted as $event) { - $start = strtotime((string)$event->date); - $duration = $this->strToDuration((string)$event->duration); - $end = $start + $duration; + $start = new DateTimeImmutable((string)$event->date); + $interval = $this->strToInterval((string)$event->duration); + $end = $start->add($interval); // skip duplicate events in fahrplan source if ( $laststart == $start ) - continue; + continue; if($lastend && $lastend < $start) { - // synthesize pause event - $pauseduration = $start - $lastend; - $program[$roomName][] = array( - 'special' => 'pause', - 'title' => round($pauseduration / 60).' minutes pause', - - 'fstart' => date('c', $lastend), - 'fend' => date('c', $start), - - 'start' => $lastend, - 'end' => $start, - 'duration' => $pauseduration, - 'room_known' => $this->isRoomMapped($roomName), - ); + // pause between talks + $pause = $this->makeEvent($lastend, $start); + $pause['special'] = 'pause'; + $pause['title'] = round($pause['duration'] / 60).' minutes pause'; + $pause['room_known'] = $this->isRoomMapped($roomName); + $program[$roomName][] = $pause; } else if(!$lastend && $daystart < $start) { - $program[$roomName][] = array( - 'special' => 'gap', - - 'fstart' => date('c', $daystart), - 'fend' => date('c', $start), - - 'start' => $daystart, - 'end' => $start, - 'duration' => $start - $daystart, - 'room_known' => $this->isRoomMapped($roomName), - ); + // gap before first talk + $gap = $this->makeEvent($daystart, $start); + $gap['special'] = 'gap'; + $gap['room_known'] = $this->isRoomMapped($roomName); + $program[$roomName][] = $gap; } $personnames = array(); if(isset($event->persons)) foreach($event->persons->person as $person) $personnames[] = (string)$person; - $program[$roomName][] = array( - 'title' => (string)$event->title, - 'speaker' => implode(', ', $personnames), - - 'fstart' => date('c', $start), - 'fend' => date('c', $end), - - 'start' => $start, - 'end' => $end, - 'duration' => $duration, - 'room_known' => $this->isRoomMapped($roomName), - 'optout' => $this->isOptout($event), - ); + // normal talk + $talk = $this->makeEvent($start, $end); + $talk['title'] = (string)$event->title; + $talk['speaker'] = implode(', ', $personnames); + $talk['room_known'] = $this->isRoomMapped($roomName); + $talk['optout'] = $this->isOptout($event); + $program[$roomName][] = $talk; $laststart = $start; $lastend = $end; } - // synthesize daychange event if(!$lastend) $lastend = $daystart; if($lastend < $dayend) { - $program[$roomName][] = array( - 'special' => 'gap', - - 'fstart' => date('c', $lastend), - 'fend' => date('c', $dayend), - - 'start' => $lastend, - 'end' => $dayend, - 'duration' => $dayend - $lastend, - ); + // gap after last talk + $gap = $this->makeEvent($lastend, $dayend); + $gap['special'] = 'gap'; + $program[$roomName][] = $gap; } if($dayidx < count($schedule->day)) { - $program[$roomName][] = array( - 'special' => 'daychange', - 'title' => 'Daychange from Day '.$dayidx.' to '.($dayidx+1), - - 'start' => $dayend, - 'end' => (int)$schedule->day[$dayidx]['start'], - 'duration' => 60*60, - ); + // daychange + $end = new DateTimeImmutable($schedule->day[$dayidx]['start']); + $daychange = $this->makeEvent($dayend, $end); + $daychange['special'] = 'daychange'; + $daychange['title'] = 'Daychange from Day '.$dayidx.' to '.($dayidx+1); + $daychange['duration'] = 3600; + $program[$roomName][] = $daychange; } } } - $mapping = $this->getScheduleToRoomSlugMapping(); if($this->getConference()->has('SCHEDULE.ROOMFILTER')) { - // sort by roomfilter + // determine roomfilter $roomfilter = $this->getConference()->get('SCHEDULE.ROOMFILTER'); // map roomfilter-rooms to room-slugs @@ -291,7 +255,7 @@ class Schedule return $e; }, $roomfilter); - // sort according to roomtilter ordering + // sort according to roomfilter ordering uksort($program, function($a, $b) use ($roomfilter) { return array_search($a, $roomfilter) - array_search($b, $roomfilter); }); @@ -300,6 +264,32 @@ class Schedule return $program; } + private function makeEvent(DateTimeImmutable $from, DateTimeImmutable $to): array { + return array( + 'fstart' => $from->format('c'), + 'fend' => $to->format('c'), + 'tstart' => $from->format('H:i'), + 'tend' => $to->format('H:i'), + + 'start' => $from->getTimestamp(), + 'end' => $to->getTimestamp(), + 'offset' => $from->getOffset(), + 'duration' => $to->getTimestamp() - $from->getTimestamp(), + ); + } + + private function intervalToDuration(DateInterval $interval): int { + $one = new DateTimeImmutable(); + $two = $one->add($interval); + return $two->getTimestamp() - $one->getTimestamp(); + } + + private function strToInterval(string $str): DateInterval + { + $parts = explode(':', $str); + return new DateInterval('PT'.$parts[0].'H'.$parts[1].'M'); + } + public function getDurationSum() { @@ -312,23 +302,18 @@ class Schedule } - - private function strToDuration($str) - { - $parts = explode(':', $str); - return ((int)$parts[0] * 60 + (int)$parts[1]) * 60; - } - public function getScheduleUrl() { return $this->getConference()->get('SCHEDULE.URL'); } + public function getScheduleCache() { return sprintf('/tmp/schedule-cache-%s.xml', $this->getConference()->getSlug()); } + public function getScheduleToRoomSlugMapping() { $mapping = array(); |