24include_once 
'./Services/Calendar/classes/class.ilCalendarRecurrence.php';
 
   25include_once(
'./Services/Calendar/classes/class.ilDateList.php');
 
   26include_once(
'./Services/Calendar/classes/class.ilTimeZone.php');
 
   27include_once(
'./Services/Calendar/classes/class.ilCalendarUtil.php');
 
   28include_once 
'./Services/Calendar/interfaces/interface.ilCalendarRecurrenceCalculation.php';
 
   69                $this->
event = $entry;
 
   70                $this->recurrence = $rec;
 
  100#               echo $this->event->getStart(); 
  101#               echo $this->event->getEnd(); 
  109                        $this->valid_dates->add($this->event->getStart());
 
  126                        $this->valid_dates->add($this->event->getStart());
 
  127                        #$this->valid_dates->add($this->event->getStart()); 
  132                $time = microtime(
true);
 
  136                #echo "ZEIT: ADJUST: ".(microtime(true) - $time).'<br>';
 
  145                        $this->frequence_context = $this->recurrence->getFrequenceType();
 
  152                        #echo "BYMONTH: ".$freq_res;
 
  155                        #echo "BYWEEKNO: ".$freq_res;
 
  158                        #echo "BYYEARDAY: ".$freq_res;
 
  162                        #echo "BYMONTHDAY: ".$freq_res;
 
  164                        #$time = microtime(true); 
  166                        #echo "ZEIT: ".(microtime(true) - $time); 
 
  167                        #echo "BYDAY: ".$freq_res;
 
  171                        #echo "BYSETPOS: ".$freq_res;
 
  187                $this->valid_dates->sort();
 
  201                $this->timezone = $this->
event->isFullday() ? 
ilTimeZone::UTC : $this->recurrence->getTimeZone();
 
  204                $this->period_start = clone $a_start;
 
  205                $this->period_end = clone $a_end;
 
  206                $this->start = clone $this->
event->getStart();
 
  210                        if($this->event->isFullday())
 
  218                                $this->period_start->switchTimeZone($this->recurrence->getTimeZone());
 
  219                                $this->period_end->switchTimeZone($this->recurrence->getTimeZone());
 
  220                                $this->start->switchTimeZone($this->recurrence->getTimeZone());
 
  226                        $this->log->write(__METHOD__.
': '.$e->getMessage());
 
  238                $time = microtime(
true);
 
  242                if($this->recurrence->getFrequenceUntilCount() > 0)
 
  250                        $optimized = clone 
$start;
 
  266                switch($this->recurrence->getFrequenceType())
 
  285                                $ilLog->write(__METHOD__.
'No frequence defined.');
 
  300                if(!$this->recurrence->getBYMONTHList())
 
  305                foreach($list->
get() as $date)
 
  307                        #echo "SEED: ".$seed;
 
  309                        foreach($this->recurrence->getBYMONTHList() as $month)
 
  311                                #echo "RULW_MONTH:".$month;
 
  320                                        #echo "BYMONTH: ".$month_date;
 
  321                                        $month_list->add($month_date);
 
  325                                        $month_list->add($date);
 
  350                if(!$this->recurrence->getBYWEEKNOList())
 
  355                foreach($list->
get() as $seed)
 
  357                        $weeks_in_year = date(
'W',mktime(0,0,0,12,28,$seed->get(
IL_CAL_FKT_DATE,
'Y',$this->timezone)));
 
  358                        $this->log->write(__METHOD__.
': Year '.$seed->get(
IL_CAL_FKT_DATE,
'Y',$this->timezone).
' has '.$weeks_in_year.
' weeks');
 
  359                        foreach($this->recurrence->getBYWEEKNOList() as $week_no)
 
  361                                $week_no = $week_no < 0 ? ($weeks_in_year + $week_no + 1) : $week_no;
 
  363                                switch($this->frequence_context)
 
  366                                                $this->log->write(__METHOD__.
': Handling BYWEEKNO in MONTHLY context');
 
  370                                                        $weeks_list->add($seed);
 
  375                                                $this->log->write(__METHOD__.
': Handling BYWEEKNO in YEARLY context');
 
  376                                                $week_diff = $week_no - $seed->get(
IL_CAL_FKT_DATE,
'W',$this->timezone);
 
  381                                                $weeks_list->add($new_week);
 
  399                if(!$this->recurrence->getBYYEARDAYList())
 
  404                foreach($list->
get() as $seed)
 
  406                        $num_days = date(
'z',mktime(0,0,0,12,31,$seed->get(
IL_CAL_FKT_DATE,
'Y',$this->timezone)));
 
  407                        $this->log->write(__METHOD__.
': Year '.$seed->get(
IL_CAL_FKT_DATE,
'Y',$this->timezone).
' has '.$num_days.
' days.');
 
  409                        foreach($this->recurrence->getBYYEARDAYList() as $day_no)
 
  411                                $day_no = $day_no < 0 ? ($num_days + $day_no + 1) : $day_no;
 
  417                                switch($this->frequence_context)
 
  423                                                        $days_list->add($new_day);
 
  430                                                        $days_list->add($new_day);
 
  437                                                        $days_list->add($new_day);
 
  442                                                $day_list->add($new_day);
 
  460                if(!$this->recurrence->getBYMONTHDAYList())
 
  465                foreach($list->
get() as $seed)
 
  475                        #$this->log->write(__METHOD__.': Month '.$seed->get(IL_CAL_FKT_DATE,'M',$this->timezone).' has '.$num_days.' days.'); 
  477                        foreach($this->recurrence->getBYMONTHDAYList() as $bymonth_no)
 
  479                                $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
 
  482                                        if($day_no < 1 or $day_no > $num_days)
 
  484                                                $this->log->write(__METHOD__.
': Ignoring BYMONTHDAY rule: '.$day_no.
' for month '.
 
  493                                switch($this->frequence_context)
 
  497                                                #var_dump("<pre>",$seed->get(IL_CAL_FKT_DATE,'z',$this->timezone),$day_no,"</pre>");
 
  500                                                        $days_list->add($new_day);
 
  508                                                        $days_list->add($new_day);
 
  514                                                $days_list->add($new_day);
 
  518                                                $h = $this->
event->isFullday() ? 0 : $seed->get(
IL_CAL_FKT_DATE,
'H',$this->timezone);
 
  519                                                $i = $this->
event->isFullday() ? 0 : $seed->get(
IL_CAL_FKT_DATE,
'i',$this->timezone);
 
  520                                                $s = $this->
event->isFullday() ? 0 : $seed->get(
IL_CAL_FKT_DATE,
's',$this->timezone);
 
  524                                                for($month = 1;$month <= 12;$month++)
 
  526                                                        #$num_days = cal_days_in_month(CAL_GREGORIAN, 
  532                                                        $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
 
  533                                                        if($day_no < 1 or $day_no > $num_days)
 
  535                                                                $this->log->write(__METHOD__.
': Ignoring BYMONTHDAY rule: '.$day_no.
' for month '.$month);
 
  541                                                                $unix = mktime(
$h,$i,$s,$month,$day_no,
$y);
 
  542                                                                $tz_obj->restoreTZ();
 
  544                                                                $days_list->add($new_day);
 
  566                if(!$this->recurrence->getBYDAYList())
 
  575                foreach($list->
get() as $seed)
 
  581                        $date_info[
'mday'] = 1;
 
  582                        $date_info[
'mon'] = 1;
 
  585                        switch($this->frequence_context)
 
  592                                        $day_sequence = $this->
getMonthWeekDays($seed_info[
'year'],$seed_info[
'mon']);
 
  602                                        $day_sequence[strtoupper(substr($seed->get(
IL_CAL_FKT_DATE,
'D'),0,2))] = array($seed_info[
'yday']);
 
  606                        foreach($this->recurrence->getBYDAYList() as $byday)
 
  609                                $day =  strtoupper(substr($byday,-2));
 
  610                                $num_by_day = (int) $byday;
 
  616                                                if(isset($day_sequence[$day][$num_by_day - 1]))
 
  618                                                        $year_day =  array($day_sequence[$day][$num_by_day - 1]);
 
  623                                                if(isset($day_sequence[$day][count($day_sequence[$day]) + $num_by_day]))
 
  625                                                        $year_day = array($day_sequence[$day][count($day_sequence[$day]) + $num_by_day]);
 
  631                                        if(isset($day_sequence[$day]))
 
  633                                                $year_day = $day_sequence[$day];
 
  636                                foreach($year_day as $day)
 
  638                                        switch($this->frequence_context)
 
  646                                                        $days_list->add($tmp_date);
 
  665                $time = microtime(
true);
 
  667                $year_days = array();
 
  672                $days = array(0 => 
'SU',1 => 
'MO',2 => 
'TU',3 => 
'WE',4 => 
'TH',5 => 
'FR',6 => 
'SA');
 
  673                for($i = 0;$i < $offset;$i++)
 
  679                for($i = 0;$i < $num_days;$i++)
 
  681                        if(($current_day = current($days)) == 
false)
 
  683                                $current_day = reset($days);
 
  685                        $year_days[$current_day][] = $i;
 
  700                static $month_days = array();
 
  702                if(isset($month_days[$year][$month]))
 
  704                        return $month_days[$year][$month];
 
  707                $month_str = $month < 10 ? (
'0'.$month) : $month; 
 
  711                $days = array(0 => 
'SU',1 => 
'MO',2 => 
'TU',3 => 
'WE',4 => 
'TH',5 => 
'FR',6 => 
'SA');
 
  712                for($i = 0;$i < $begin_month_info[
'wday'];$i++)
 
  718                        if(($current_day = current($days)) == 
false)
 
  720                                $current_day = reset($days);
 
  722                        $month_days[$year][$month][$current_day][] = $i;
 
  725                return $month_days[$year][$month];
 
  737                $days = array(0 => 
'SU',1 => 
'MO',2 => 
'TU',3 => 
'WE',4 => 
'TH',5 => 
'FR',6 => 
'SA');
 
  739                $start_day = $seed_info[
'yday'] - $seed_info[
'wday'];
 
  740                foreach($days as $num => $day)
 
  742                        $week_days[$day][] = $start_day++;
 
  758                if(!$this->recurrence->getBYSETPOSList())
 
  764                $candidates = $list->
get();
 
  765                $candidates_count = count($candidates);
 
  766                foreach($this->recurrence->getBYSETPOSList() as $position)
 
  768                        if($position > 0 and $date = $list->
getAtPosition($position))
 
  770                                $pos_list->add($date);
 
  772                        if($position < 0 and $date = $list->getAtPosition($candidates_count + $position + 1))
 
  774                                $pos_list->add($date);
 
  796                foreach($list->
get() as $check_date)
 
  800                                #echo 'Removed: '.$check_date.'<br/>'; 
  801                                $list->
remove($check_date);
 
  805                #echo 'Until date '.$this->recurrence->getFrequenceUntilDate(); 
  808                if($this->recurrence->getFrequenceUntilCount())
 
  813                                if(count($this->valid_dates->get()) < $this->recurrence->getFrequenceUntilCount())
 
  815                                        $this->valid_dates->add(
$res);
 
  819                                        $this->limit_reached = 
true;
 
  825                elseif($this->recurrence->getFrequenceUntilDate())
 
  827                        #echo 'Until date '.$this->recurrence->getFrequenceUntilDate(); 
  828                        $date = $this->recurrence->getFrequenceUntilDate();
 
  831                                #echo 'Check date '.$res; 
  834                                        #echo 'Limit reached'; 
  835                                        $this->limit_reached = 
true;
 
  838                                $this->valid_dates->add(
$res);
 
  843                $this->valid_dates->merge($list);
 
  854                if(!$this->recurrence->getExclusionDates())
 
  858                foreach($this->recurrence->getExclusionDates() as $excl)
 
  860                        $this->valid_dates->removeByDAY($excl->getDate());
 
  881                if($this->event->isFullday())
 
  883                        return new ilDate($a_date,$a_format_type);
 
  888                        return new ilDateTime($a_date,$a_format_type,$this->timezone);
 
  900                return $this->recurrence->validate();
 
Calculates an ilDateList for a given calendar entry and recurrence rule.
getMonthWeekDays($year, $month)
get a list of month days
validateRecurrence()
validate recurrence
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
applyBYMONTHDAYRules(ilDateList $list)
Apply BYMONTHDAY rules.
__construct(ilDatePeriod $entry, ilCalendarRecurrenceCalculation $rec)
@access public
applyBYSETPOSRules(ilDateList $list)
Apply BYSETPOST rules.
applyBYMONTHRules(ilDateList $list)
Apply BYMONTH rules.
applyBYYEARDAYRules(ilDateList $list)
Apply BYYEARDAY rules.
getYearWeekDays(ilDateTime $seed)
get a list of year week days according to the BYMONTH rule
incrementByFrequency($start)
increment starting time by frequency
calculateDateListByMonth($a_month, $a_year)
calculate day list by month(s) uses a cache of calculated recurring events @access public
calculateDateList(ilDateTime $a_start, ilDateTime $a_end, $a_limit=-1)
calculate date list
initDateList()
init date list
applyLimits(ilDateList $list)
Apply limits (count or until)
adjustTimeZones(ilDateTime $a_start, ilDateTime $a_end)
Adjust timezone.
getWeekWeekDays($seed_info)
get weedays of week
applyBYWEEKNORules(ilDateList $list)
Apply BYWEEKNO rules (1 to 53 and -1 to -53).
optimizeStartingTime()
optimize starting time
applyBYDAYRules(ilDateList $list)
Apply BYDAY rules.
static _getMaxDayOfMonth($a_year, $a_month)
get max day of month 2008,2 => 29
static _isLeapYear($a_year)
check if a given year is a leap year
remove(ilDateTime $remove)
remove from list
getAtPosition($a_pos)
get item at specific position
Class for DateTime exceptions.
@classDescription Date and time handling
static _equals(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
Check if two date are equal.
switchTimeZone($a_timezone_identifier='')
Switch timezone.
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
get($a_format, $a_format_str='', $a_tz='')
get formatted date
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
static _restoreDefaultTimeZone()
restore default timezone to server timezone
static _setDefaultTimeZone($a_tz)
set default timezone
static _getInstance($a_tz='')
get instance by timezone