I am attempting to implement Martin Fowler's class model for recurring events in PHP. The DateTime and DatePeriod PHP objects look like they might be a good fit for dealing with temporal expressions. The issue is that I need to be able to perform UNION, INTERSECT and DIFFERENCE operations on the DatePeriods so that I can calculate expressions like "every Tuesday except dates that are even". That example would require the difference of an 'every Tuesday' DatePeriod and an 'even date' DatePeriod.
DatePeriod is iterable, but it is not accessible to standard array handling functions like array_intersect()
and array_diff()
. (I wish!) So I tried changing the DatePeriod to an array with $ap=array_to_iterator($dp)
. This works mostly as expected, except that the DateTime objects that DatePeriod contains do not have a __toString()
method, something that many array functions require.
My most recent attempt comes closest:
function recur_union($p1,$p2){
$a1=(is_object($p1)) ? iterator_to_array($p1):$p1;
$d_arr=recur_difference($p2,$a1);
return array_merge($a1,$d_arr);
}
function recur_difference($p1,$p2){
$arr=array();
$a2=(is_object($p2)) ? iterator_to_array($p2):$p2;
foreach($p1 as $dt){
if(!in_array($dt,$a2))$arr[]=$dt;
}
return $arr;
}
$p1=new DatePeriod(date_create('2008-01-01'),DateInterval::createFromDateString( "+2 days" ),date_create('2008-12-31'));
$p2=new DatePeriod(date_create('2008-01-01'),DateInterval::createFromDateString( "+7 days" ),date_create('2008-12-31'));
$au=recur_union($p1,$p2);
$ad=recur_difference($p1,$p2);
echo $au, $ad;
Unfortunately, it appears that the DatePeriods $p1 and $p2 get clobbered during processing. If I do recur_union($p1,$p2)
first, I get a valid result. If done after recur_difference($p1,$p2)
, recur_union
returns an empty array. The same occurs for recur_difference
.
Question #1: Can anyone explain why iterator_to_array
seems to obliterate the original DatePeriod?
Since my DatePeriods were being clobbered, I thought I'd try cloning them. But the following causes IE8 to display the "cannot display the webpage" message and FF3.5 to do nothing:
$p1=new DatePeriod(date_create('2008-01-01'),DateInterval::createFromDateString( "+2 days" ),date_create('2008-12-31'));
$p2=new DatePeriod(date_create('2008-01-01'),DateInterval::createFromDateString( "+7 days" ),date_create('2008-12-31'));
$a1=clone $p1;
$a2=clone $p2;
$au=recur_union($p1,$p2);
$ad=recur_difference($a1,$a2);
echo $au, $ad;
Question #2: What is going on with the clones?
Thanks All!