compareDateTime() public method

Compares this to another date object, including times, to see which one is greater (later). Assumes that the dates are in the same timezone.
public compareDateTime ( mixed $other ) : integer
$other mixed The date to compare to.
return integer == 0 if they are equal >= 1 if $this is greater (later) <= -1 if $other is greater (later)
Ejemplo n.º 1
0
 /**
  * Retrieve the busy times from this event within the given timeframe.  This
  * is trivial for non-recurring events but recurring events need to be
  * expanded.
  *
  * @param Horde_Date $startDate The start point.
  * @param Horde_Date $endDate   The end point.
  *
  * @return array The list of busy times (only the start times of the event).
  */
 public function getBusyTimes(Horde_Date $startDate, Horde_Date $endDate)
 {
     if (!$this->recurs()) {
         if ($startDate->compareDateTime($this->_start) > 0 || $endDate->compareDateTime($this->_start) < 0) {
             return array();
         }
         return array($this->_start->timestamp());
     } else {
         $result = array();
         $next = $this->_recurrence->nextRecurrence($startDate);
         while ($next) {
             if ($endDate->compareDateTime($next) < 0) {
                 break;
             }
             if (!$this->_recurrence->hasException($next->year, $next->month, $next->mday)) {
                 $result[] = $next->timestamp();
             }
             $next->mday++;
             $next = $this->_recurrence->nextRecurrence($next);
         }
         return $result;
     }
 }
Ejemplo n.º 2
0
 /**
  * Is a Horde_Date within this span?
  *
  * @param Horde_Date $date
  */
 public function includes($date)
 {
     return $this->begin->compareDateTime($date) <= 0 && $this->end->compareDateTime($date) >= 0;
 }
Ejemplo n.º 3
0
 public function readForm()
 {
     global $prefs, $session;
     // Event owner.
     $targetcalendar = Horde_Util::getFormData('targetcalendar');
     if (strpos($targetcalendar, '\\')) {
         list(, $this->creator) = explode('\\', $targetcalendar, 2);
     } elseif (!isset($this->_id)) {
         $this->creator = $GLOBALS['registry']->getAuth();
     }
     // Basic fields.
     $this->title = Horde_Util::getFormData('title', $this->title);
     $this->description = Horde_Util::getFormData('description', $this->description);
     $this->location = Horde_Util::getFormData('location', $this->location);
     $this->timezone = Horde_Util::getFormData('timezone', $this->timezone);
     $this->private = (bool) Horde_Util::getFormData('private');
     // URL.
     $url = Horde_Util::getFormData('eventurl', $this->url);
     if (strlen($url)) {
         // Analyze and re-construct.
         $url = @parse_url($url);
         if ($url) {
             if (function_exists('http_build_url')) {
                 if (empty($url['path'])) {
                     $url['path'] = '/';
                 }
                 $url = http_build_url($url);
             } else {
                 $new_url = '';
                 if (isset($url['scheme'])) {
                     $new_url .= $url['scheme'] . '://';
                 }
                 if (isset($url['user'])) {
                     $new_url .= $url['user'];
                     if (isset($url['pass'])) {
                         $new_url .= ':' . $url['pass'];
                     }
                     $new_url .= '@';
                 }
                 if (isset($url['host'])) {
                     // Convert IDN hosts to ASCII.
                     if (function_exists('idn_to_ascii')) {
                         $url['host'] = @idn_to_ascii($url['host']);
                     } elseif (Horde_Mime::is8bit($url['host'])) {
                         //throw new Kronolith_Exception(_("Invalid character in URL."));
                         $url['host'] = '';
                     }
                     $new_url .= $url['host'];
                 }
                 if (isset($url['path'])) {
                     $new_url .= $url['path'];
                 }
                 if (isset($url['query'])) {
                     $new_url .= '?' . $url['query'];
                 }
                 if (isset($url['fragment'])) {
                     $new_url .= '#' . $url['fragment'];
                 }
                 $url = $new_url;
             }
         }
     }
     $this->url = $url;
     // Status.
     $this->status = Horde_Util::getFormData('status', $this->status);
     // Attendees.
     $attendees = $session->get('kronolith', 'attendees', Horde_Session::TYPE_ARRAY);
     if (!is_null($newattendees = Horde_Util::getFormData('attendees'))) {
         $newattendees = Kronolith::parseAttendees(trim($newattendees));
         foreach ($newattendees as $email => $attendee) {
             if (!isset($attendees[$email])) {
                 $attendees[$email] = $attendee;
             }
         }
         foreach (array_keys($attendees) as $email) {
             if (!isset($newattendees[$email])) {
                 unset($attendees[$email]);
             }
         }
     }
     $this->attendees = $attendees;
     // Event start.
     $allDay = Horde_Util::getFormData('whole_day');
     if ($start_date = Horde_Util::getFormData('start_date')) {
         // From ajax interface.
         $this->start = Kronolith::parseDate($start_date . ' ' . Horde_Util::getFormData('start_time'), true, $this->timezone);
         if ($allDay) {
             $this->start->hour = $this->start->min = $this->start->sec = 0;
         }
     } else {
         // From traditional interface.
         $start = Horde_Util::getFormData('start');
         $start_year = $start['year'];
         $start_month = $start['month'];
         $start_day = $start['day'];
         $start_hour = Horde_Util::getFormData('start_hour');
         $start_min = Horde_Util::getFormData('start_min');
         $am_pm = Horde_Util::getFormData('am_pm');
         if (!$prefs->getValue('twentyFour')) {
             if ($am_pm == 'PM') {
                 if ($start_hour != 12) {
                     $start_hour += 12;
                 }
             } elseif ($start_hour == 12) {
                 $start_hour = 0;
             }
         }
         if (Horde_Util::getFormData('end_or_dur') == 1) {
             if ($allDay) {
                 $start_hour = 0;
                 $start_min = 0;
                 $dur_day = 0;
                 $dur_hour = 24;
                 $dur_min = 0;
             } else {
                 $dur_day = (int) Horde_Util::getFormData('dur_day');
                 $dur_hour = (int) Horde_Util::getFormData('dur_hour');
                 $dur_min = (int) Horde_Util::getFormData('dur_min');
             }
         }
         $this->start = new Horde_Date(array('hour' => $start_hour, 'min' => $start_min, 'month' => $start_month, 'mday' => $start_day, 'year' => $start_year), $this->timezone);
     }
     // Event end.
     if ($end_date = Horde_Util::getFormData('end_date')) {
         // From ajax interface.
         $this->end = Kronolith::parseDate($end_date . ' ' . Horde_Util::getFormData('end_time'), true, $this->timezone);
         if ($allDay) {
             $this->end->hour = $this->end->min = $this->end->sec = 0;
             $this->end->mday++;
         }
     } elseif (Horde_Util::getFormData('end_or_dur') == 1) {
         // Event duration from traditional interface.
         $this->end = new Horde_Date(array('hour' => $start_hour + $dur_hour, 'min' => $start_min + $dur_min, 'month' => $start_month, 'mday' => $start_day + $dur_day, 'year' => $start_year));
     } else {
         // From traditional interface.
         $end = Horde_Util::getFormData('end');
         $end_year = $end['year'];
         $end_month = $end['month'];
         $end_day = $end['day'];
         $end_hour = Horde_Util::getFormData('end_hour');
         $end_min = Horde_Util::getFormData('end_min');
         $end_am_pm = Horde_Util::getFormData('end_am_pm');
         if (!$prefs->getValue('twentyFour')) {
             if ($end_am_pm == 'PM') {
                 if ($end_hour != 12) {
                     $end_hour += 12;
                 }
             } elseif ($end_hour == 12) {
                 $end_hour = 0;
             }
         }
         $this->end = new Horde_Date(array('hour' => $end_hour, 'min' => $end_min, 'month' => $end_month, 'mday' => $end_day, 'year' => $end_year), $this->timezone);
         if ($this->end->compareDateTime($this->start) < 0) {
             $this->end = new Horde_Date($this->start);
         }
     }
     $this->allday = false;
     // Alarm.
     if (!is_null($alarm = Horde_Util::getFormData('alarm'))) {
         if ($alarm) {
             $value = Horde_Util::getFormData('alarm_value');
             $unit = Horde_Util::getFormData('alarm_unit');
             if ($value == 0) {
                 $value = $unit = 1;
             }
             $this->alarm = $value * $unit;
             // Notification.
             if (Horde_Util::getFormData('alarm_change_method')) {
                 $types = Horde_Util::getFormData('event_alarms');
                 $methods = array();
                 if (!empty($types)) {
                     foreach ($types as $type) {
                         $methods[$type] = array();
                         switch ($type) {
                             case 'notify':
                                 $methods[$type]['sound'] = Horde_Util::getFormData('event_alarms_sound');
                                 break;
                             case 'mail':
                                 $methods[$type]['email'] = Horde_Util::getFormData('event_alarms_email');
                                 break;
                             case 'popup':
                                 break;
                         }
                     }
                 }
                 $this->methods = $methods;
             } else {
                 $this->methods = array();
             }
         } else {
             $this->alarm = 0;
             $this->methods = array();
         }
     }
     // Recurrence.
     $this->recurrence = $this->readRecurrenceForm($this->start, $this->timezone, $this->recurrence);
     // Convert to local timezone.
     $this->setTimezone(false);
     // Resources
     $existingResources = $this->_resources;
     if (Horde_Util::getFormData('isajax', false)) {
         $resources = array();
     } else {
         $resources = $session->get('kronolith', 'resources', Horde_Session::TYPE_ARRAY);
     }
     $newresources = Horde_Util::getFormData('resources');
     if (!empty($newresources)) {
         foreach (explode(',', $newresources) as $id) {
             try {
                 $resource = Kronolith::getDriver('Resource')->getResource($id);
             } catch (Kronolith_Exception $e) {
                 $GLOBALS['notification']->push($e->getMessage(), 'horde.error');
                 continue;
             }
             if (!$resource instanceof Kronolith_Resource_Group || $resource->isFree($this)) {
                 $resources[$resource->getId()] = array('attendance' => Kronolith::PART_REQUIRED, 'response' => Kronolith::RESPONSE_NONE, 'name' => $resource->get('name'));
             } else {
                 $GLOBALS['notification']->push(_("No resources from this group were available"), 'horde.error');
             }
         }
     }
     $this->_resources = $resources;
     // Check if we need to remove any resources
     $merged = $existingResources + $this->_resources;
     $delete = array_diff(array_keys($existingResources), array_keys($this->_resources));
     foreach ($delete as $key) {
         // Resource might be declined, in which case it won't have the event
         // on it's calendar.
         if ($merged[$key]['response'] != Kronolith::RESPONSE_DECLINED) {
             try {
                 Kronolith::getDriver('Resource')->getResource($key)->removeEvent($this);
             } catch (Kronolith_Exception $e) {
                 $GLOBALS['notification']->push('foo', 'horde.error');
             }
         }
     }
     // Tags.
     $this->tags = Horde_Util::getFormData('tags', $this->tags);
     // Geolocation
     if (Horde_Util::getFormData('lat') && Horde_Util::getFormData('lon')) {
         $this->geoLocation = array('lat' => Horde_Util::getFormData('lat'), 'lon' => Horde_Util::getFormData('lon'), 'zoom' => Horde_Util::getFormData('zoom'));
     }
     $this->initialized = true;
 }
Ejemplo n.º 4
0
 /**
  * @throws Kronolith_Exception
  */
 public function listAlarms($date, $fullevent = false)
 {
     $allevents = $this->listEvents($date, null, array('has_alarm' => true));
     $events = array();
     foreach (array_keys($allevents) as $eventId) {
         $event = $this->getEvent($eventId);
         if (!$event->recurs()) {
             $start = new Horde_Date($event->start);
             $start->min -= $event->alarm;
             if ($start->compareDateTime($date) <= 0 && $date->compareDateTime($event->end) <= -1) {
                 $events[] = $fullevent ? $event : $eventId;
             }
         } else {
             if ($next = $event->recurrence->nextRecurrence($date)) {
                 if ($event->recurrence->hasException($next->year, $next->month, $next->mday)) {
                     continue;
                 }
                 $start = new Horde_Date($next);
                 $start->min -= $event->alarm;
                 $end = new Horde_Date(array('year' => $next->year, 'month' => $next->month, 'mday' => $next->mday, 'hour' => $event->end->hour, 'min' => $event->end->min, 'sec' => $event->end->sec));
                 if ($start->compareDateTime($date) <= 0 && $date->compareDateTime($end) <= -1) {
                     if ($fullevent) {
                         $event->start = $start;
                         $event->end = $end;
                         $events[] = $event;
                     } else {
                         $events[] = $eventId;
                     }
                 }
             }
         }
     }
     return is_array($events) ? $events : array();
 }
Ejemplo n.º 5
0
Archivo: Sql.php Proyecto: horde/horde
 /**
  *
  * @param Horde_Date $date    The date to list alarms for
  * @param boolean $fullevent  Return the full event objects?
  *
  * @return array  An array of event ids, or Kronolith_Event objects
  * @throws Kronolith_Exception
  */
 public function listAlarms($date, $fullevent = false)
 {
     $allevents = $this->listEvents($date, null, array('has_alarm' => true));
     $events = array();
     foreach ($allevents as $dayevents) {
         foreach ($dayevents as $event) {
             if (!$event->recurs()) {
                 $start = new Horde_Date($event->start);
                 $start->min -= $event->alarm;
                 if ($start->compareDateTime($date) <= 0 && $date->compareDateTime($event->end) <= -1) {
                     $events[] = $fullevent ? $event : $event->id;
                 }
             } else {
                 // Need to start at the beginning of the day to catch the
                 // case where we might be within the event's timespan
                 // when we call this, hence nextRecurrence() would miss the
                 // current event.
                 $start = clone $date;
                 $start->min = 0;
                 $start->hour = 0;
                 $start->sec = 0;
                 if ($next = $event->recurrence->nextRecurrence($start)) {
                     if ($event->recurrence->hasException($next->year, $next->month, $next->mday)) {
                         continue;
                     }
                     $start = new Horde_Date($next);
                     $start->min -= $event->alarm;
                     $diff = $event->start->diff($event->end);
                     $end = new Horde_Date(array('year' => $next->year, 'month' => $next->month, 'mday' => $next->mday + $diff, 'hour' => $event->end->hour, 'min' => $event->end->min, 'sec' => $event->end->sec));
                     if ($start->compareDateTime($date) <= 0 && $date->compareDateTime($end) <= -1) {
                         if ($fullevent) {
                             $event->start = $next;
                             $event->end = $end;
                             $events[] = $event;
                         } else {
                             $events[] = $event->id;
                         }
                     }
                 }
             }
         }
     }
     return $events;
 }
Ejemplo n.º 6
0
 /**
  * Adds an event to all the days it covers.
  *
  * @param array $result           The current result list.
  * @param Kronolith_Event $event  An event object.
  * @param Horde_Date $eventStart  The event's start at the actual
  *                                recurrence.
  * @param Horde_Date $eventEnd    The event's end at the actual recurrence.
  * @param boolean $json           Store the results of the events' toJson()
  *                                method?
  */
 public static function addCoverDates(&$results, $event, $eventStart, $eventEnd, $json)
 {
     $loopDate = new Horde_Date($eventStart->year, $eventStart->month, $eventStart->mday);
     $allDay = $event->isAllDay();
     while ($loopDate->compareDateTime($eventEnd) <= 0) {
         if (!$allDay || $loopDate->compareDateTime($eventEnd) != 0) {
             $addEvent = clone $event;
             $addEvent->start = $eventStart;
             $addEvent->end = $eventEnd;
             if ($loopDate->compareDate($eventStart) != 0) {
                 $addEvent->first = false;
             }
             if ($loopDate->compareDate($eventEnd) != 0) {
                 $addEvent->last = false;
             }
             if ($addEvent->recurs() && $addEvent->recurrence->hasCompletion($loopDate->year, $loopDate->month, $loopDate->mday)) {
                 $addEvent->status = Kronolith::STATUS_CANCELLED;
             }
             $results[$loopDate->dateString()][$addEvent->id] = $json ? $addEvent->toJson($allDay) : $addEvent;
         }
         $loopDate->mday++;
     }
 }
Ejemplo n.º 7
0
 /**
  * Reads form/post data and updates this event's properties.
  *
  * @param  Kronolith_Event|null $existing  If this is an exception event
  *                                         this is taken as the base event.
  *                                         @since 4.2.6
  *
  */
 public function readForm(Kronolith_Event $existing = null)
 {
     global $prefs, $session;
     // Event owner.
     $targetcalendar = Horde_Util::getFormData('targetcalendar');
     if (strpos($targetcalendar, '\\')) {
         list(, $this->creator) = explode('\\', $targetcalendar, 2);
     } elseif (!isset($this->_id)) {
         $this->creator = $GLOBALS['registry']->getAuth();
     }
     // Basic fields.
     $this->title = Horde_Util::getFormData('title', $this->title);
     $this->description = Horde_Util::getFormData('description', $this->description);
     $this->location = Horde_Util::getFormData('location', $this->location);
     $this->timezone = Horde_Util::getFormData('timezone', $this->timezone);
     $this->private = (bool) Horde_Util::getFormData('private');
     // URL.
     $url = Horde_Util::getFormData('eventurl', $this->url);
     if (strlen($url)) {
         // Analyze and re-construct.
         $url = @parse_url($url);
         if ($url) {
             if (function_exists('http_build_url')) {
                 if (empty($url['path'])) {
                     $url['path'] = '/';
                 }
                 $url = http_build_url($url);
             } else {
                 $new_url = '';
                 if (isset($url['scheme'])) {
                     $new_url .= $url['scheme'] . '://';
                 }
                 if (isset($url['user'])) {
                     $new_url .= $url['user'];
                     if (isset($url['pass'])) {
                         $new_url .= ':' . $url['pass'];
                     }
                     $new_url .= '@';
                 }
                 if (isset($url['host'])) {
                     // Convert IDN hosts to ASCII.
                     if (function_exists('idn_to_ascii')) {
                         $url['host'] = @idn_to_ascii($url['host']);
                     } elseif (Horde_Mime::is8bit($url['host'])) {
                         //throw new Kronolith_Exception(_("Invalid character in URL."));
                         $url['host'] = '';
                     }
                     $new_url .= $url['host'];
                 }
                 if (isset($url['path'])) {
                     $new_url .= $url['path'];
                 }
                 if (isset($url['query'])) {
                     $new_url .= '?' . $url['query'];
                 }
                 if (isset($url['fragment'])) {
                     $new_url .= '#' . $url['fragment'];
                 }
                 $url = $new_url;
             }
         }
     }
     $this->url = $url;
     // Status.
     $this->status = Horde_Util::getFormData('status', $this->status);
     // Attendees.
     $attendees = $session->get('kronolith', 'attendees', Horde_Session::TYPE_ARRAY);
     if (!is_null($newattendees = Horde_Util::getFormData('attendees'))) {
         $newattendees = Kronolith::parseAttendees(trim($newattendees));
         foreach ($newattendees as $email => $attendee) {
             if (!isset($attendees[$email])) {
                 $attendees[$email] = $attendee;
             }
         }
         foreach (array_keys($attendees) as $email) {
             if (!isset($newattendees[$email])) {
                 unset($attendees[$email]);
             }
         }
     }
     $this->attendees = $attendees;
     // Event start.
     $allDay = Horde_Util::getFormData('whole_day');
     if ($start_date = Horde_Util::getFormData('start_date')) {
         // From ajax interface.
         $this->start = Kronolith::parseDate($start_date . ' ' . Horde_Util::getFormData('start_time'), true, $this->timezone);
         if ($allDay) {
             $this->start->hour = $this->start->min = $this->start->sec = 0;
         }
     } else {
         // From traditional interface.
         $start = Horde_Util::getFormData('start');
         $start_year = $start['year'];
         $start_month = $start['month'];
         $start_day = $start['day'];
         $start_hour = Horde_Util::getFormData('start_hour');
         $start_min = Horde_Util::getFormData('start_min');
         $am_pm = Horde_Util::getFormData('am_pm');
         if (!$prefs->getValue('twentyFour')) {
             if ($am_pm == 'PM') {
                 if ($start_hour != 12) {
                     $start_hour += 12;
                 }
             } elseif ($start_hour == 12) {
                 $start_hour = 0;
             }
         }
         if (Horde_Util::getFormData('end_or_dur') == 1) {
             if ($allDay) {
                 $start_hour = 0;
                 $start_min = 0;
                 $dur_day = 0;
                 $dur_hour = 24;
                 $dur_min = 0;
             } else {
                 $dur_day = (int) Horde_Util::getFormData('dur_day');
                 $dur_hour = (int) Horde_Util::getFormData('dur_hour');
                 $dur_min = (int) Horde_Util::getFormData('dur_min');
             }
         }
         $this->start = new Horde_Date(array('hour' => $start_hour, 'min' => $start_min, 'month' => $start_month, 'mday' => $start_day, 'year' => $start_year), $this->timezone);
     }
     // Event end.
     if ($end_date = Horde_Util::getFormData('end_date')) {
         // From ajax interface.
         $this->end = Kronolith::parseDate($end_date . ' ' . Horde_Util::getFormData('end_time'), true, $this->timezone);
         if ($allDay) {
             $this->end->hour = $this->end->min = $this->end->sec = 0;
             $this->end->mday++;
         }
     } elseif (Horde_Util::getFormData('end_or_dur') == 1) {
         // Event duration from traditional interface.
         $this->end = new Horde_Date(array('hour' => $start_hour + $dur_hour, 'min' => $start_min + $dur_min, 'month' => $start_month, 'mday' => $start_day + $dur_day, 'year' => $start_year));
     } else {
         // From traditional interface.
         $end = Horde_Util::getFormData('end');
         $end_year = $end['year'];
         $end_month = $end['month'];
         $end_day = $end['day'];
         $end_hour = Horde_Util::getFormData('end_hour');
         $end_min = Horde_Util::getFormData('end_min');
         $end_am_pm = Horde_Util::getFormData('end_am_pm');
         if (!$prefs->getValue('twentyFour')) {
             if ($end_am_pm == 'PM') {
                 if ($end_hour != 12) {
                     $end_hour += 12;
                 }
             } elseif ($end_hour == 12) {
                 $end_hour = 0;
             }
         }
         $this->end = new Horde_Date(array('hour' => $end_hour, 'min' => $end_min, 'month' => $end_month, 'mday' => $end_day, 'year' => $end_year), $this->timezone);
         if ($this->end->compareDateTime($this->start) < 0) {
             $this->end = new Horde_Date($this->start);
         }
     }
     $this->allday = false;
     // Alarm.
     if (!is_null($alarm = Horde_Util::getFormData('alarm'))) {
         if ($alarm) {
             $value = Horde_Util::getFormData('alarm_value');
             $unit = Horde_Util::getFormData('alarm_unit');
             if ($value == 0) {
                 $value = $unit = 1;
             }
             $this->alarm = $value * $unit;
             // Notification.
             if (Horde_Util::getFormData('alarm_change_method')) {
                 $types = Horde_Util::getFormData('event_alarms');
                 $methods = array();
                 if (!empty($types)) {
                     foreach ($types as $type) {
                         $methods[$type] = array();
                         switch ($type) {
                             case 'notify':
                                 $methods[$type]['sound'] = Horde_Util::getFormData('event_alarms_sound');
                                 break;
                             case 'mail':
                                 $methods[$type]['email'] = Horde_Util::getFormData('event_alarms_email');
                                 break;
                             case 'popup':
                                 break;
                         }
                     }
                 }
                 $this->methods = $methods;
             } else {
                 $this->methods = array();
             }
         } else {
             $this->alarm = 0;
             $this->methods = array();
         }
     }
     // Recurrence.
     $this->recurrence = $this->readRecurrenceForm($this->start, $this->timezone, $this->recurrence);
     // Convert to local timezone.
     $this->setTimezone(false);
     $this->_handleResources($existing);
     // Tags.
     $this->tags = Horde_Util::getFormData('tags', $this->tags);
     // Geolocation
     if (Horde_Util::getFormData('lat') && Horde_Util::getFormData('lon')) {
         $this->geoLocation = array('lat' => Horde_Util::getFormData('lat'), 'lon' => Horde_Util::getFormData('lon'), 'zoom' => Horde_Util::getFormData('zoom'));
     }
     $this->initialized = true;
 }
 /**
  * Finds the next recurrence of this event that's after $afterDate.
  *
  * @param Horde_Date|string $after  Return events after this date.
  *
  * @return Horde_Date|boolean  The date of the next recurrence or false
  *                             if the event does not recur after
  *                             $afterDate.
  */
 public function nextRecurrence($after)
 {
     if (!$after instanceof Horde_Date) {
         $after = new Horde_Date($after);
     } else {
         $after = clone $after;
     }
     // Make sure $after and $this->start are in the same TZ
     $after->setTimezone($this->start->timezone);
     if ($this->start->compareDateTime($after) >= 0) {
         return clone $this->start;
     }
     if ($this->recurInterval == 0 && empty($this->rdates)) {
         return false;
     }
     switch ($this->getRecurType()) {
         case self::RECUR_DAILY:
             $diff = $this->start->diff($after);
             $recur = ceil($diff / $this->recurInterval);
             if ($this->recurCount && $recur >= $this->recurCount) {
                 return false;
             }
             $recur *= $this->recurInterval;
             $next = $this->start->add(array('day' => $recur));
             if ((!$this->hasRecurEnd() || $next->compareDateTime($this->recurEnd) <= 0) && $next->compareDateTime($after) >= 0) {
                 return $next;
             }
             break;
         case self::RECUR_WEEKLY:
             if (empty($this->recurData)) {
                 return false;
             }
             $start_week = Horde_Date_Utils::firstDayOfWeek($this->start->format('W'), $this->start->year);
             $start_week->timezone = $this->start->timezone;
             $start_week->hour = $this->start->hour;
             $start_week->min = $this->start->min;
             $start_week->sec = $this->start->sec;
             // Make sure we are not at the ISO-8601 first week of year while
             // still in month 12...OR in the ISO-8601 last week of year while
             // in month 1 and adjust the year accordingly.
             $week = $after->format('W');
             if ($week == 1 && $after->month == 12) {
                 $theYear = $after->year + 1;
             } elseif ($week >= 52 && $after->month == 1) {
                 $theYear = $after->year - 1;
             } else {
                 $theYear = $after->year;
             }
             $after_week = Horde_Date_Utils::firstDayOfWeek($week, $theYear);
             $after_week->timezone = $this->start->timezone;
             $after_week_end = clone $after_week;
             $after_week_end->mday += 7;
             $diff = $start_week->diff($after_week);
             $interval = $this->recurInterval * 7;
             $repeats = floor($diff / $interval);
             if ($diff % $interval < 7) {
                 $recur = $diff;
             } else {
                 /**
                  * If the after_week is not in the first week interval the
                  * search needs to skip ahead a complete interval. The way it is
                  * calculated here means that an event that occurs every second
                  * week on Monday and Wednesday with the event actually starting
                  * on Tuesday or Wednesday will only have one incidence in the
                  * first week.
                  */
                 $recur = $interval * ($repeats + 1);
             }
             if ($this->hasRecurCount()) {
                 $recurrences = 0;
                 /**
                  * Correct the number of recurrences by the number of events
                  * that lay between the start of the start week and the
                  * recurrence start.
                  */
                 $next = clone $start_week;
                 while ($next->compareDateTime($this->start) < 0) {
                     if ($this->recurOnDay((int) pow(2, $next->dayOfWeek()))) {
                         $recurrences--;
                     }
                     ++$next->mday;
                 }
                 if ($repeats > 0) {
                     $weekdays = $this->recurData;
                     $total_recurrences_per_week = 0;
                     while ($weekdays > 0) {
                         if ($weekdays % 2) {
                             $total_recurrences_per_week++;
                         }
                         $weekdays = ($weekdays - $weekdays % 2) / 2;
                     }
                     $recurrences += $total_recurrences_per_week * $repeats;
                 }
             }
             $next = clone $start_week;
             $next->mday += $recur;
             while ($next->compareDateTime($after) < 0 && $next->compareDateTime($after_week_end) < 0) {
                 if ($this->hasRecurCount() && $next->compareDateTime($after) < 0 && $this->recurOnDay((int) pow(2, $next->dayOfWeek()))) {
                     $recurrences++;
                 }
                 ++$next->mday;
             }
             if ($this->hasRecurCount() && $recurrences >= $this->recurCount) {
                 return false;
             }
             if (!$this->hasRecurEnd() || $next->compareDateTime($this->recurEnd) <= 0) {
                 if ($next->compareDateTime($after_week_end) >= 0) {
                     return $this->nextRecurrence($after_week_end);
                 }
                 while (!$this->recurOnDay((int) pow(2, $next->dayOfWeek())) && $next->compareDateTime($after_week_end) < 0) {
                     ++$next->mday;
                 }
                 if (!$this->hasRecurEnd() || $next->compareDateTime($this->recurEnd) <= 0) {
                     if ($next->compareDateTime($after_week_end) >= 0) {
                         return $this->nextRecurrence($after_week_end);
                     } else {
                         return $next;
                     }
                 }
             }
             break;
         case self::RECUR_MONTHLY_DATE:
             $start = clone $this->start;
             if ($after->compareDateTime($start) < 0) {
                 $after = clone $start;
             } else {
                 $after = clone $after;
             }
             // If we're starting past this month's recurrence of the event,
             // look in the next month on the day the event recurs.
             if ($after->mday > $start->mday) {
                 ++$after->month;
                 $after->mday = $start->mday;
             }
             // Adjust $start to be the first match.
             $offset = $after->month - $start->month + ($after->year - $start->year) * 12;
             $offset = floor(($offset + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval;
             if ($this->recurCount && $offset / $this->recurInterval >= $this->recurCount) {
                 return false;
             }
             $start->month += $offset;
             $count = $offset / $this->recurInterval;
             do {
                 if ($this->recurCount && $count++ >= $this->recurCount) {
                     return false;
                 }
                 // Bail if we've gone past the end of recurrence.
                 if ($this->hasRecurEnd() && $this->recurEnd->compareDateTime($start) < 0) {
                     return false;
                 }
                 if ($start->isValid()) {
                     return $start;
                 }
                 // If the interval is 12, and the date isn't valid, then we
                 // need to see if February 29th is an option. If not, then the
                 // event will _never_ recur, and we need to stop checking to
                 // avoid an infinite loop.
                 if ($this->recurInterval == 12 && ($start->month != 2 || $start->mday > 29)) {
                     return false;
                 }
                 // Add the recurrence interval.
                 $start->month += $this->recurInterval;
             } while (true);
             break;
         case self::RECUR_MONTHLY_WEEKDAY:
             // Start with the start date of the event.
             $estart = clone $this->start;
             // What day of the week, and week of the month, do we recur on?
             if (isset($this->recurNthDay)) {
                 $nth = $this->recurNthDay;
                 $weekday = log($this->recurData, 2);
             } else {
                 $nth = ceil($this->start->mday / 7);
                 $weekday = $estart->dayOfWeek();
             }
             // Adjust $estart to be the first candidate.
             $offset = $after->month - $estart->month + ($after->year - $estart->year) * 12;
             $offset = floor(($offset + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval;
             // Adjust our working date until it's after $after.
             $estart->month += $offset - $this->recurInterval;
             $count = $offset / $this->recurInterval;
             do {
                 if ($this->recurCount && $count++ >= $this->recurCount) {
                     return false;
                 }
                 $estart->month += $this->recurInterval;
                 $next = clone $estart;
                 $next->setNthWeekday($weekday, $nth);
                 if ($next->compareDateTime($after) < 0) {
                     // We haven't made it past $after yet, try again.
                     continue;
                 }
                 if ($this->hasRecurEnd() && $next->compareDateTime($this->recurEnd) > 0) {
                     // We've gone past the end of recurrence; we can give up
                     // now.
                     return false;
                 }
                 // We have a candidate to return.
                 break;
             } while (true);
             return $next;
         case self::RECUR_YEARLY_DATE:
             // Start with the start date of the event.
             $estart = clone $this->start;
             $after = clone $after;
             if ($after->month > $estart->month || $after->month == $estart->month && $after->mday > $estart->mday) {
                 ++$after->year;
                 $after->month = $estart->month;
                 $after->mday = $estart->mday;
             }
             // Seperate case here for February 29th
             if ($estart->month == 2 && $estart->mday == 29) {
                 while (!Horde_Date_Utils::isLeapYear($after->year)) {
                     ++$after->year;
                 }
             }
             // Adjust $estart to be the first candidate.
             $offset = $after->year - $estart->year;
             if ($offset > 0) {
                 $offset = floor(($offset + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval;
                 $estart->year += $offset;
             }
             // We've gone past the end of recurrence; give up.
             if ($this->recurCount && $offset >= $this->recurCount) {
                 return false;
             }
             if ($this->hasRecurEnd() && $this->recurEnd->compareDateTime($estart) < 0) {
                 return false;
             }
             return $estart;
         case self::RECUR_YEARLY_DAY:
             // Check count first.
             $dayofyear = $this->start->dayOfYear();
             $count = ($after->year - $this->start->year) / $this->recurInterval + 1;
             if ($this->recurCount && ($count > $this->recurCount || $count == $this->recurCount && $after->dayOfYear() > $dayofyear)) {
                 return false;
             }
             // Start with a rough interval.
             $estart = clone $this->start;
             $estart->year += floor($count - 1) * $this->recurInterval;
             // Now add the difference to the required day of year.
             $estart->mday += $dayofyear - $estart->dayOfYear();
             // Add an interval if the estimation was wrong.
             if ($estart->compareDate($after) < 0) {
                 $estart->year += $this->recurInterval;
                 $estart->mday += $dayofyear - $estart->dayOfYear();
             }
             // We've gone past the end of recurrence; give up.
             if ($this->hasRecurEnd() && $this->recurEnd->compareDateTime($estart) < 0) {
                 return false;
             }
             return $estart;
         case self::RECUR_YEARLY_WEEKDAY:
             // Start with the start date of the event.
             $estart = clone $this->start;
             // What day of the week, and week of the month, do we recur on?
             if (isset($this->recurNthDay)) {
                 $nth = $this->recurNthDay;
                 $weekday = log($this->recurData, 2);
             } else {
                 $nth = ceil($this->start->mday / 7);
                 $weekday = $estart->dayOfWeek();
             }
             // Adjust $estart to be the first candidate.
             $offset = floor(($after->year - $estart->year + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval;
             // Adjust our working date until it's after $after.
             $estart->year += $offset - $this->recurInterval;
             $count = $offset / $this->recurInterval;
             do {
                 if ($this->recurCount && $count++ >= $this->recurCount) {
                     return false;
                 }
                 $estart->year += $this->recurInterval;
                 $next = clone $estart;
                 $next->setNthWeekday($weekday, $nth);
                 if ($next->compareDateTime($after) < 0) {
                     // We haven't made it past $after yet, try again.
                     continue;
                 }
                 if ($this->hasRecurEnd() && $next->compareDateTime($this->recurEnd) > 0) {
                     // We've gone past the end of recurrence; we can give up
                     // now.
                     return false;
                 }
                 // We have a candidate to return.
                 break;
             } while (true);
             return $next;
     }
     // fall-back to RDATE properties
     if (!empty($this->rdates)) {
         $next = clone $this->start;
         foreach ($this->rdates as $rdate) {
             $next->year = $rdate->year;
             $next->month = $rdate->month;
             $next->mday = $rdate->mday;
             if ($next->compareDateTime($after) > 0) {
                 return $next;
             }
         }
     }
     // We didn't find anything, the recurType was bad, or something else
     // went wrong - return false.
     return false;
 }
Ejemplo n.º 9
0
 /**
  * Adds an event to all the days it covers.
  *
  * @param array $result              The current result list.
  * @param Kronolith_Event $event     An event object.
  * @param Horde_Date $eventStart     The event's start of the actual
  *                                   recurrence.
  * @param Horde_Date $eventEnd       The event's end of the actual
  *                                   recurrence.
  * @param boolean $json              Store the results of the events'
  *                                   toJson() method?
  * @param Horde_Date $originalStart  The actual starting time of a single
  *                                   event spanning multiple days.
  * @param Horde_Date $originalEnd    The actual ending time of a single
  *                                   event spanning multiple days.
  */
 public static function addCoverDates(&$results, $event, $eventStart, $eventEnd, $json, $originalStart = null, $originalEnd = null, Horde_Date $endDate = null)
 {
     $loopDate = new Horde_Date(array('month' => $eventStart->month, 'mday' => $eventStart->mday, 'year' => $eventStart->year));
     $allDay = $event->isAllDay();
     while ($loopDate->compareDateTime($eventEnd) <= 0 && $loopDate->compareDateTime($endDate) <= 0) {
         if (!$allDay || $loopDate->compareDateTime($eventEnd) != 0) {
             $addEvent = clone $event;
             if ($originalStart) {
                 $addEvent->originalStart = $originalStart;
             }
             if ($originalEnd) {
                 $addEvent->originalEnd = $originalEnd;
             }
             /* If this is the start day, set the start time to
              * the real start time, otherwise set it to
              * 00:00 */
             if ($loopDate->compareDate($eventStart) != 0) {
                 $addEvent->start = clone $loopDate;
                 $addEvent->start->hour = $addEvent->start->min = $addEvent->start->sec = 0;
                 $addEvent->first = false;
             } else {
                 $addEvent->start = $eventStart;
             }
             /* If this is the end day, set the end time to the
              * real event end, otherwise set it to 23:59. */
             if ($loopDate->compareDate($eventEnd) != 0) {
                 $addEvent->end = clone $loopDate;
                 $addEvent->end->hour = 23;
                 $addEvent->end->min = $addEvent->end->sec = 59;
                 $addEvent->last = false;
             } else {
                 $addEvent->end = $eventEnd;
             }
             if ($addEvent->recurs() && $addEvent->recurrence->hasCompletion($loopDate->year, $loopDate->month, $loopDate->mday)) {
                 $addEvent->status = Kronolith::STATUS_CANCELLED;
             }
             $results[$loopDate->dateString()][$addEvent->id] = $json ? $addEvent->toJson(array('all_day' => $allDay)) : $addEvent;
         }
         $loopDate->mday++;
     }
 }
Ejemplo n.º 10
0
Archivo: Taf.php Proyecto: horde/horde
 /**
  * Parses TAF data.
  *
  * TAF KLGA 271734Z 271818 11007KT P6SM -RA SCT020 BKN200
  *     FM2300 14007KT P6SM SCT030 BKN150
  *     FM0400 VRB03KT P6SM SCT035 OVC080 PROB30 0509 P6SM -RA BKN035
  *     FM0900 VRB03KT 6SM -RA BR SCT015 OVC035
  *         TEMPO 1215 5SM -RA BR SCT009 BKN015
  *         BECMG 1517 16007KT P6SM NSW SCT015 BKN070
  *
  * @param array $data  The TAF encoded weather data, spilt on line endings.
  *
  * @return  array  An array of forecast data. Keys include:
  *    - station: (string) The station identifier.
  *    - dataRaw: (string) The raw TAF data.
  *    - update:  (timestamp) Timestamp of last update.
  *    - validFrom: (Horde_Date) The valid FROM time.
  *    - validTo: (Horde_Date) The valid TO time.
  *    - time: (array) An array of Horde_Service_Weather_Period objects for
  *      each available valid time provided by the TAF report.
  */
 protected function _parse(array $data)
 {
     $tafCode = $this->_getTafCodes();
     // Eliminate trailing information
     for ($i = 0; $i < sizeof($data); $i++) {
         if (strpos($data[$i], '=') !== false) {
             $data[$i] = substr($data[$i], 0, strpos($data[$i], '='));
             $data = array_slice($data, 0, $i + 1);
             break;
         }
     }
     // Ok, we have correct data, start with parsing the first line for the last update
     $forecastData = array();
     $forecastData['station'] = '';
     $forecastData['dataRaw'] = implode(' ', $data);
     $forecastData['update'] = strtotime(trim($data[0]) . ' GMT');
     $forecastData['updateRaw'] = trim($data[0]);
     // and prepare the rest for stepping through
     array_shift($data);
     $taf = explode(' ', preg_replace('/\\s{2,}/', ' ', implode(' ', $data)));
     // The timeperiod the data gets added to
     $fromTime = '';
     // If we have FMCs (Forecast Meteorological Conditions), we need this
     $fmcCount = 0;
     // Pointer to the array we add the data to
     $pointer =& $forecastData;
     for ($i = 0; $i < sizeof($taf); $i++) {
         $taf[$i] = trim($taf[$i]);
         if (!strlen($taf[$i])) {
             continue;
         }
         // Init
         $result = array();
         $resultVF = array();
         $lresult = array();
         $found = false;
         foreach ($tafCode as $key => $regexp) {
             // Check if current code matches current taf snippet
             if (($found = preg_match('/^' . $regexp . '$/i', $taf[$i], $result)) == true) {
                 $insert = array();
                 switch ($key) {
                     case 'station':
                         $pointer['station'] = $result[0];
                         unset($tafCode['station']);
                         break;
                     case 'valid':
                         $pointer['validRaw'] = $result[0];
                         // Generates the timeperiod the report is valid for
                         list($year, $month, $day) = explode('-', gmdate('Y-m-d', $forecastData['update']));
                         // Date is in next month
                         if ($result[1] < $day) {
                             $month++;
                         }
                         $pointer['validFrom'] = new Horde_Date(array('hour' => $result[2], 'month' => $month, 'mday' => $result[1], 'year' => $year), 'GMT');
                         $pointer['validTo'] = new Horde_Date(array('hour' => $result[4], 'month' => $month, 'mday' => $result[3], 'year' => $year), 'GMT');
                         unset($tafCode['valid']);
                         // Now the groups will start, so initialize the time groups
                         $pointer['time'] = array();
                         $start_time = new Horde_Date(array('year' => $year, 'month' => $month, 'mday' => $result[1], 'hour' => $result[2]), 'UTC');
                         $fromTime = (string) $start_time;
                         $pointer['time'][$fromTime] = array();
                         // Set pointer to the first timeperiod
                         $pointer =& $pointer['time'][$fromTime];
                         break;
                     case 'wind':
                         if ($result[5] == 'KTS') {
                             $result[5] = 'KT';
                         }
                         $pointer['wind'] = round(Horde_Service_Weather::convertSpeed($result[2], $result[5], $this->_unitMap[self::UNIT_KEY_SPEED]));
                         if ($result[1] == 'VAR' || $result[1] == 'VRB') {
                             $pointer['windDegrees'] = Horde_Service_Weather_Translation::t('Variable');
                             $pointer['windDirection'] = Horde_Service_Weather_Translation::t('Variable');
                         } else {
                             $pointer['windDegrees'] = $result[1];
                             $pointer['windDirection'] = Horde_Service_Weather::degToDirection($result[1]);
                         }
                         if (is_numeric($result[4])) {
                             $pointer['windGust'] = round(Horde_Service_Weather::convertSpeed($result[4], $result[5], $this->_unitMap[self::UNIT_KEY_SPEED]));
                         }
                         if (isset($probability)) {
                             $pointer['windProb'] = $probability;
                             unset($probability);
                         }
                         unset($tafCode['wind']);
                         break;
                     case 'visFrac':
                         // Possible fractional visibility here.
                         // Check if it matches with the next TAF piece for visibility
                         if (!isset($taf[$i + 1]) || !preg_match('/^' . $tafCode['visibility'] . '$/i', $result[1] . ' ' . $taf[$i + 1], $resultVF)) {
                             // No next TAF piece available or not matching.
                             $found = false;
                             break;
                         }
                         // Match. Hand over result and advance TAF
                         $key = 'visibility';
                         $result = $resultVF;
                         $i++;
                         // Fall through
                     // Fall through
                     case 'visibility':
                         $pointer['visQualifier'] = Horde_Service_Weather_Translation::t('AT');
                         if (is_numeric($result[1]) && $result[1] == 9999) {
                             // Upper limit of visibility range
                             $visibility = Horde_Service_Weather::convertDistance(10, 'km', $this->_unitMap[self::UNIT_KEY_DISTANCE]);
                             $pointer['visQualifier'] = Horde_Service_Weather_Translation::t('BEYOND');
                         } elseif (is_numeric($result[1])) {
                             // 4-digit visibility in m
                             $visibility = Horde_Service_Weather::convertDistance($result[1], 'm', $this->_unitMap[self::UNIT_KEY_DISTANCE]);
                         } elseif (!isset($result[11]) || $result[11] != 'CAVOK') {
                             if ($result[3] == 'M') {
                                 $pointer['visQualifier'] = Horde_Service_Weather_Translation::t('BELOW');
                             } elseif ($result[3] == 'P') {
                                 $pointer['visQualifier'] = Horde_Service_Weather_Translation::t('BEYOND');
                             }
                             if (is_numeric($result[5])) {
                                 // visibility as one/two-digit number
                                 $visibility = Horde_Service_Weather::convertDistance($result[5], $result[10], $this->_unitMap[self::UNIT_KEY_DISTANCE]);
                             } else {
                                 // the y/z part, add if we had a x part (see visibility1)
                                 if (is_numeric($result[7])) {
                                     $visibility = Horde_Service_Weather::convertDistance($result[7] + $result[8] / $result[9], $result[10], $this->_unitMap[self::UNIT_KEY_DISTANCE]);
                                 } else {
                                     $visibility = Horde_Service_Weather::convertDistance($result[8] / $result[9], $result[10], $this->_unitMap[self::UNIT_KEY_DISTANCE]);
                                 }
                             }
                         } else {
                             $pointer['visQualifier'] = Horde_Service_Weather_Translation::t('BEYOND');
                             $visibility = Horde_Service_Weather::convertDistance(10, 'km', $this->_unitMap[self::UNIT_KEY_DISTANCE]);
                             $pointer['clouds'] = array(array('amount' => Horde_Service_Weather_Translation::t('Clear below'), 'height' => 5000));
                             $pointer['condition'] = Horde_Service_Weather_Translation::t('No significant weather');
                         }
                         if (isset($probability)) {
                             $pointer['visProb'] = $probability;
                             unset($probability);
                         }
                         $pointer['visibility'] = $visibility;
                         break;
                     case 'condition':
                         // First some basic setups
                         if (!isset($pointer['condition'])) {
                             $pointer['condition'] = '';
                         } elseif (strlen($pointer['condition']) > 0) {
                             $pointer['condition'] .= ',';
                         }
                         if (in_array(strtolower($result[0]), $this->_conditions)) {
                             // First try matching the complete string
                             $pointer['condition'] .= ' ' . $this->_conditions[strtolower($result[0])];
                         } else {
                             // No luck, match part by part
                             array_shift($result);
                             $result = array_unique($result);
                             foreach ($result as $condition) {
                                 if (strlen($condition) > 0) {
                                     $pointer['condition'] .= ' ' . $this->_conditions[strtolower($condition)];
                                 }
                             }
                         }
                         $pointer['condition'] = trim($pointer['condition']);
                         if (isset($probability)) {
                             $pointer['condition'] .= ' (' . $probability . '% ' . Horde_Service_Weather_Translation::t('probability') . ').';
                             unset($probability);
                         }
                         break;
                     case 'clouds':
                         if (!isset($pointer['clouds'])) {
                             $pointer['clouds'] = array();
                         }
                         if (sizeof($result) == 5) {
                             // Only amount and height
                             $cloud = array('amount' => $this->_clouds[strtolower($result[3])]);
                             if ($result[4] == '///') {
                                 $cloud['height'] = Horde_Service_Weather_Translation::t('station level or below');
                             } else {
                                 $cloud['height'] = $result[4] * 100;
                             }
                         } elseif (sizeof($result) == 6) {
                             // Amount, height and type
                             $cloud = array('amount' => $this->_clouds[strtolower($result[3])], 'type' => $this->_clouds[strtolower($result[5])]);
                             if ($result[4] == '///') {
                                 $cloud['height'] = Horde_Service_Weather_Translation::t('station level or below');
                             } else {
                                 $cloud['height'] = $result[4] * 100;
                             }
                         } else {
                             // SKC or CLR or NSC
                             $cloud = array('amount' => $this->_clouds[strtolower($result[0])]);
                         }
                         if (isset($probability)) {
                             $cloud['prob'] = $probability;
                             unset($probability);
                         }
                         $pointer['clouds'][] = $cloud;
                         break;
                     case 'windshear':
                         // Parse windshear, if available
                         if ($result[4] == 'KTS') {
                             $result[4] = 'KT';
                         }
                         $pointer['windshear'] = round(Horde_Service_Weather::convertSpeed($result[3], $result[4], $this->_unitMap[self::UNIT_KEY_SPEED]));
                         $pointer['windshearHeight'] = $result[1] * 100;
                         $pointer['windshearDegrees'] = $result[2];
                         $pointer['windshearDirection'] = Horde_Service_Weather::degToDirection($result[2]);
                         break;
                     case 'tempmax':
                         $forecastData['temperatureHigh'] = Horde_Service_Weather::convertTemperature($result[1], 'c', $this->_unitMap[self::UNIT_KEY_TEMP]);
                         break;
                     case 'tempmin':
                         // Parse max/min temperature
                         $forecastData['temperatureLow'] = Horde_Service_Weather::convertTemperature($result[1], 'c', $this->_unitMap[self::UNIT_KEY_TEMP]);
                         break;
                     case 'tempmaxmin':
                         $forecastData['temperatureHigh'] = Horde_Service_Weather::convertTemperature($result[1], 'c', $this->_unitMap[self::UNIT_KEY_TEMP]);
                         $forecastData['temperatureLow'] = Horde_Service_Weather::convertTemperature($result[4], 'c', $this->_unitMap[self::UNIT_KEY_TEMP]);
                         break;
                     case 'from':
                         // Next timeperiod is coming up, prepare array and
                         // set pointer accordingly
                         $fromTime = clone $start_time;
                         if (sizeof($result) > 2) {
                             // The ICAO way
                             $fromTime->hour = $result[2];
                             $fromTime->min = $result[3];
                         } else {
                             // The Australian way (Hey mates!)
                             $fromTime->hour = $result[1];
                         }
                         if ($start_time->compareDateTime($fromTime) >= 1) {
                             $fromTime->mday++;
                         }
                         $fromTime = (string) $fromTime;
                         $forecastData['time'][$fromTime] = array();
                         $fmcCount = 0;
                         $pointer =& $forecastData['time'][$fromTime];
                         break;
                     case 'fmc':
                         // Test, if this is a probability for the next FMC
                         if (isset($result[2]) && preg_match('/^BECMG|TEMPO$/i', $taf[$i + 1], $lresult)) {
                             // Set type to BECMG or TEMPO
                             $type = $lresult[0];
                             // Set probability
                             $probability = $result[2];
                             // Now extract time for this group
                             if (preg_match('/^(\\d{2})(\\d{2})$/i', $taf[$i + 2], $lresult)) {
                                 $from = clone $start_time;
                                 $from->hour = $lresult[1];
                                 if ($start_time->compareDateTime($from) >= 1) {
                                     $from->mday++;
                                 }
                                 $to = clone $from;
                                 $to->hour = $lresult[2];
                                 if ($start_time->compareDateTime($to) >= 1) {
                                     $to->mday++;
                                 }
                                 // As we now have type, probability and time for this FMC
                                 // from our TAF, increase field-counter
                                 $i += 2;
                             } else {
                                 // No timegroup present, so just increase field-counter by one
                                 $i += 1;
                             }
                         } elseif (preg_match('/^(\\d{2})(\\d{2})\\/(\\d{2})(\\d{2})$/i', $taf[$i + 1], $lresult)) {
                             // Normal group, set type and use extracted time
                             $type = $result[1];
                             // Check for PROBdd
                             if (isset($result[2])) {
                                 $probability = $result[2];
                             }
                             $from = clone $start_time;
                             $from->hour = $lresult[2];
                             if ($start_time->compareDateTime($from) >= 1) {
                                 $from->mday++;
                             }
                             $to = clone $from;
                             $to->hour = $lresult[4];
                             if ($start_time->compareDateTime($to) >= 1) {
                                 $to->mday++;
                             }
                             // Same as above, we have a time for this FMC from our TAF,
                             // increase field-counter
                             $i += 1;
                         } elseif (isset($result[2])) {
                             // This is either a PROBdd or a malformed TAF with missing timegroup
                             $probability = $result[2];
                         }
                         // Handle the FMC, generate neccessary array if it's the first...
                         if (isset($type)) {
                             if (!isset($forecastData['time'][$fromTime]['fmc'])) {
                                 $forecastData['time'][$fromTime]['fmc'] = array();
                             }
                             $forecastData['time'][$fromTime]['fmc'][$fmcCount] = array();
                             // ...and set pointer.
                             $pointer =& $forecastData['time'][$fromTime]['fmc'][$fmcCount];
                             $fmcCount++;
                             // Insert data
                             $pointer['type'] = $type;
                             unset($type);
                             if (isset($from)) {
                                 $pointer['from'] = $from;
                                 $pointer['to'] = $to;
                                 unset($from, $to);
                             }
                             if (isset($probability)) {
                                 $pointer['probability'] = $probability;
                                 unset($probability);
                             }
                         }
                         break;
                     default:
                         // Do nothing
                         break;
                 }
                 if ($found) {
                     break;
                 }
             }
         }
     }
     return $forecastData;
 }