From def4803124150ffa584a41106aeb2865498787ca Mon Sep 17 00:00:00 2001 From: Jim Hu Date: Tue, 16 Dec 2008 07:55:50 +0000 Subject: progress on recurrence --- functions/parse/end_vevent.php | 33 ++++++++------- functions/parse/recur_functions.php | 80 +++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 22 deletions(-) (limited to 'functions/parse') diff --git a/functions/parse/end_vevent.php b/functions/parse/end_vevent.php index 5cf2c35..de8539f 100644 --- a/functions/parse/end_vevent.php +++ b/functions/parse/end_vevent.php @@ -199,16 +199,18 @@ variables ending in date are in phpical date format: YYYYMMDD variables ending with time are in phpical time format: HHMM variables ending in unixtime are in unixtime -mArray_begin and mArray_end are set in initialization by date_range.php and may be overwritten by rss_common.php. These should be the default for start_range and end_range unixtimes. Conditions where overwrite these: - COUNT < 1,000,000 - we have to count occurrences; reset next_range_unixtime starting value +mArray_begin and mArray_end are set in initialization by date_range.php and may be overwritten by rss_common.php. + +$start_date_unixtime should be the default for starting the range. Need this for the intervals to work out (e.g. every other day, week, month etc) +mArray_end should be the default for end_range unixtimes. +Conditions where overwrite these: $until_unixtime < $mArray_end - stop iterating early !isset($rrule_array['FREQ']) - only iterate once, set the end_range_unixtime to the end_date_unixtime Note that start_range_unixtime and end_range_unixtime are not the same as start_date_unixtime and end_date_unixtime */ -$next_range_unixtime = $mArray_begin; $end_range_unixtime = $mArray_end+60*60*24; $start_date_unixtime = strtotime($start_date); -if($count < 1000000) $next_range_unixtime = $start_date_unixtime; +$next_range_unixtime = $start_date_unixtime; if(isset($until) && $end_range_unixtime > $until_unixtime) $end_range_unixtime = $until_unixtime; if(!isset($rrule_array['FREQ'])){ $end_range_unixtime = strtotime($end_date); @@ -225,7 +227,7 @@ one $next_range_time per repeat, but the BYXXX rules may write more than one eve $next_date_time handles those instances within a $freq_type */ #echo "
$summary\n\tstart mArray time:".date("Ymd his",$mArray_begin)."\n\tstart range time:".date("Ymd his",$next_range_unixtime)."\n\tend range time ".date("Ymd his",$end_range_unixtime)."
"; $recur_data = array(); -while ($next_range_unixtime <= $end_range_unixtime) { +while ($next_range_unixtime <= $end_range_unixtime && $count > 0) { $year = date('Y', $next_range_unixtime); $month = date('m', $next_range_unixtime); # pick the right compare function from date_functions.php @@ -240,12 +242,20 @@ while ($next_range_unixtime <= $end_range_unixtime) { add_recur(expand_byday($next_range_unixtime)); break; case 'month': - $next_date_unixtime = mktime(12,0,0,$month,date('d',$start_unixtime),$year); echo "month".date("Ymd his",$next_date_unixtime); - add_recur(($next_date_unixtime)); + $times = expand_bymonthday(array($next_range_unixtime)); + foreach($times as $time){ + add_recur(expand_byday($time)); + } break; case 'year': - $next_date_unixtime = mktime(12,0,0,date('m',$start_unixtime),date('d',$start_unixtime),$year); echo "year:$hour,$min,0,".date('m',$start_unixtime).",".date('d',$start_unixtime).",$year".date("Ymd his",$next_date_unixtime);print_r($datetime); - add_recur(($next_date_unixtime)); + $times = expand_bymonth($next_range_unixtime); + $times = expand_byweekno($times); + $times = expand_byyearday($times); + $times = expand_bymonthday($times); + + foreach($times as $time){ + add_recur(expand_byday($time)); + } break; default: add_recur($start_unixtime); @@ -253,16 +263,11 @@ while ($next_range_unixtime <= $end_range_unixtime) { } $next_range_unixtime = strtotime('+'.$interval.' '.$freq_type, $next_range_unixtime); } #end while loop -$recur_data = array_unique($recur_data); sort($recur_data); echo "
$summary recur_data:";
 #var_dump($recur_data);
 foreach($recur_data as $time) echo "\n".date("Ymd his",$time);
 echo "
"; -if ($count < count($recur_data)){ - $arr = array_slice($recur_data,0,$count); - $recur_data =$arr; -} # use recur_data array to write the master array // use the same code to write the data instead of always changing it 5 times diff --git a/functions/parse/recur_functions.php b/functions/parse/recur_functions.php index 5b845b3..5cab6cf 100644 --- a/functions/parse/recur_functions.php +++ b/functions/parse/recur_functions.php @@ -24,8 +24,10 @@ BYxxx rule parts modify the recurrence in some manner. BYxxx rule */ function add_recur($times,$freq=''){ - global $recur_data; + global $recur_data, $count, $mArray_begin, $mArray_end; if (!is_array($times)) $times = array($times); + $times = array_unique($times); + sort($times); /*BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR, BYMINUTE, BYSECOND and BYSETPOS*/ $times = restrict_bymonth($times,$freq); @@ -35,15 +37,60 @@ function add_recur($times,$freq=''){ $times = restrict_byday($times,$freq); $times = restrict_bysetpos($times,$freq); - foreach ($times as $time) if(isset($time)) $recur_data[] = $time; + foreach ($times as $time){ + if(isset($time) ) $count--; + if($time >= $mArray_begin && $time <= $mArray_end && $count >= 0) $recur_data[] = $time; + } return; } +function expand_bymonth($time){ + global $bymonth, $year, $start_unixtime; + if(empty($bymonth)) $bymonth = date("m", $start_unixtime); + foreach ($bymonth as $m) $times[] = strtotime("$year".str_pad($m,2,"0",STR_PAD_LEFT).date("d",$start_unixtime)); + return $times; +} +function expand_byweekno($times){ + global $byweekno, $year; + if (empty($byweekno)) return $times; + $py = $year-1; + $ny = $year+1; + foreach($times as $time){ + foreach($byweekno as $weekno){ + if($yearday >= 0) $day = strtotime("Jan 1 $year +$weekno weeks"); + else $day = strtotime("Jan 1 $year $weekno weeks"); + if(date("Y",$day == $year)) $new_times[] = $day; + } + } + return $new_times; +} + +function expand_byyearday($times){ + global $byyearday, $year; + if (empty($byyearday)) return $times; + $py = $year-1; + $ny = $year+1; + foreach($times as $time){ + foreach($byyearday as $yearday){ + if($yearday > 0) $day = strtotime("Dec 31 $py +$yearday days"); + else $day = strtotime("Jan 1 $ny $yearday days"); + if(date("Y",$day == $year)) $new_times[] = $day; + } + } + return $new_times; +} + +function expand_bymonthday($times){ + global $bymonthday, $year, $month; + if (empty($bymonthday)) return $times; + foreach($times as $time) foreach($bymonthday as $monthday) $new_times[] = strtotime("$year.$month".str_pad($monthday,2,"0",STR_PAD_LEFT)); + return $new_times; +} function expand_byday($time){ - global $freq_type, $byday, $wkst3char; + global $freq_type, $byday, $wkst3char, $year, $month, $start_unixtime; + if (empty($byday)) return array(strtotime("$year$month".date("d",$start_unixtime))); $the_sunday = dateOfWeek(date("Ymd",$time), $wkst3char); # echo "$freq_type, ".print_r($byday,true)."$wkst3char $the_sunday"; - if (empty($byday)) $byday[] = strtoupper(substr(date('D', $time), 0, 2)); foreach($byday as $key=>$day) { /* set $byday_arr [0] => byday string, e.g. 4TH @@ -61,10 +108,23 @@ function expand_byday($time){ }else{ $next_date_time = strtotime("next $on_day",$next_date_time) + (12 * 60 * 60); } - default: - $next_date_time = strtotime($byday_arr[1].$byday_arr[2].$on_day, $time); + $times[] = $next_date_time; + break; + case 'month': + case 'year': + $week_arr = array(1,2,3,4,5); + if(!isset($byday_arr[2])) $week_arr = array($byday_arr[2]); + $month_start = strtotime(date("Ym01",$time)); + foreach($week_arr as $week){ + $next_date_time = strtotime($byday_arr[1].$week.$on_day, $month_start); + # check that we're still in the same month + if (date("m",$next_date_time) == date("m",$month_start) ) $times[] = $next_date_time; + } + break; + default: + $month_start = strtotime(date("Ym01",$time)); + $next_date_time = strtotime($byday_arr[1].$byday_arr[2].$on_day, $month_start); } - $times[] = $next_date_time; } return $times; } @@ -107,5 +167,9 @@ function restrict_byday($times,$freq=''){ function restrict_bysetpos($times,$freq=''){ global $rrule_array, $bysetpos; if(empty($bysetpos)) return $times; - + $n = count($times); + foreach($bysetpos as $setpos){ + $new_times[] = array_slice($times, $setpos, 1); + } + return $new_times; } \ No newline at end of file -- cgit v1.2.3