I have a function that implements parts of reading iCal repetition rules, and returns a list of dates when a certain event takes place.Questions/Concerns of mineAny comments on the use of anonymous functions? I added them to keep the code as DRY as possible.One thing I rather dislike is the line return strtotime('+' . $increment . ' ' . $rrule_freq_map[$rrule['FREQ']], $start_timestamp); which casts from integer to string and back for no good reason. Couldn't think of a better way to accomplish the adding of time.On a Drupal specific note, maybe the use of date in $single_day_output() should be replaced with format_date, but I'm not sure if there are any gains from that.$next_timestamp() will break if used in more than one location. Currently not an issue, would be interesting to hear suggestions on that./** * Render the date and times of events. * * Has some internal helper functions do not make sense outside of this scope. */function _bornholm_custom_calendar_event_dates($datetime) {  // Ensure we have the date_repeat_split_rrule().  module_load_include('inc', 'date_api', 'date_api_ical');  $start_timestamp = strtotime($datetime['value']);  $start_day = date('Y-m-d', strtotime($datetime['value']));  $end_day = (isset($datetime['value2'])) ? date('Y-m-d', strtotime($datetime['value2'])) : NULL;  $end_timestamp = (isset($datetime['value2'])) ? strtotime($datetime['value2']) : NULL;  $output = '';  // Build the output for a single days event information.  $single_day_output = function($timestamp) {    $output = t('@day d. @date t. @time', array(      '@day' => t(date('D', $timestamp)),      '@date' => date('d.m.Y', $timestamp),      '@time' => date('H:i', $timestamp),    ));    return ucfirst($output);  };  // Check whether or not the current has a repeat rule.  $repeats = function ($datetime) {    if ($datetime['rrule'] !== NULL) {      list($rrule, $exceptions, $additions) = date_repeat_split_rrule($datetime['rrule']);      if ($rrule['FREQ'] !== 'NONE') {        return $rrule;      }    }    return NULL;  };  // When an event repeats, step forward the timestamp once.  $next_timestamp = function($rrule, $start_timestamp) {    static $count = 0;    $rrule_freq_map = array(      'DAILY' => 'day',      'WEEKLY' => 'week',      'MONTHLY' => 'month',    );    $increment = $count++ * $rrule['INTERVAL'];    return strtotime('+' . $increment . ' ' . $rrule_freq_map[$rrule['FREQ']], $start_timestamp);  };  if ($rrule = $repeats($datetime)) {    for ($i = 0; $i < $rrule['COUNT'] && $i < 100; $i++) {      $new_timestamp = $next_timestamp($rrule, $start_timestamp);      if ($end_day === NULL || $start_day === $end_day) {        $output .= $single_day_output($new_timestamp);        if ($end_timestamp) {          $output .= ' - ' . date('H:i', $new_timestamp + ($end_timestamp - $start_timestamp));        }      }      else {        $output .= $single_day_output($new_timestamp) . ' ' . t('until') . '<br/>' . $single_day_output($new_timestamp + ($end_timestamp - $start_timestamp)) . '<br/>';      }    }  }  else {    if ($end_day === NULL || $start_day === $end_day) {      $output = $single_day_output($start_timestamp);      if ($end_timestamp) {        $output .= ' - ' . date('H:i', $end_timestamp);      }    }    else {      $output = $single_day_output($start_timestamp) . ' ' . t('until') . '<br/>' . $single_day_output($end_timestamp);    }  }  return $output;}
Basic function to output repeating dates from iCal format
php;datetime;drupal