Temporary expressions with DatePeriod?

I am trying to implement Martin Fowler's class model for recurring events in PHP. DateTime and DatePeriod PHP objects look like they are good at solving temporary expressions. The problem is that I need to be able to perform UNION, INTERSECT and DIFFERENCE operations on DatePeriods so that I can evaluate expressions like "every Tuesday except for dates that are even". This example would require the difference between DatePeriod "every Tuesday" and "date dates".

DatePeriod is iterable, but not available for standard array functions like array_intersect()

and array_diff()

. (I want!) So I tried to change the DatePeriod to an array using $ap=array_to_iterator($dp)

. This works mostly as expected, except that DateTime objects that contain a DatePeriod do not have a method __toString()

, which many array functions require.

My most recent attempt comes close:

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 looks like DatePeriods $ p1 and $ p2 are getting knocked out during processing. If I do it first recur_union($p1,$p2)

, I get a valid result. If done after recur_difference($p1,$p2)

, recur_union

returns an empty array. The same thing happens with recur_difference

.

Question # 1: Can anyone explain why iterator_to_array

it seems to erase the original DatePeriod?

Since my DatePeriods got knocked down, I thought I'd try cloning them. But the following causes IE8 to display the "do not display webpage" message and FF3.5 does 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 happens to the clones?

Thanks everyone!

+2


source to share


1 answer


I had a similar question last year, although for me I was having difficulty linking it to the persistent layer. For the application layer, one approach is to split the job into one set of classes that handles the given operations (intersection, union, difference) and one that handles "temporary expressions" (every month, last day of the month). Temporary classes can then be put together to create arbitrarily complex date conditions.



I wrote about this topic and provided sample classes here and.

+1


source







All Articles