title: temporal expressions with DatePeriod?
body: <p>I am attempting to implement <a href="http://www.martinfowler.com/apsupp/recurring.pdf" rel="nofollow noreferrer">Martin Fowler's class model for recurring events</a> in PHP. The <a href="http://ca3.php.net/manual/en/class.datetime.php" rel="nofollow noreferrer">DateTime</a> and <a href="http://ca3.php.net/manual/en/class.dateperiod.php" rel="nofollow noreferrer">DatePeriod</a> 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.</p>
  
  <p>DatePeriod is iterable, but it is not accessible to standard array handling functions like <code>array_intersect()</code> and <code>array_diff()</code>. (I wish!) So I tried changing the DatePeriod to an array with <code>$ap=array_to_iterator($dp)</code>. This works mostly as expected, except that the DateTime objects that DatePeriod contains do not have a <code>__toString()</code> method, something that many array functions require. </p>
  
  <p>My most recent attempt comes closest:</p>
  
  <pre><code>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;
  </code></pre>
  
  <p>Unfortunately, it appears that the DatePeriods $p1 and $p2 get clobbered during processing. If I do <code>recur_union($p1,$p2)</code> first, I get a valid result. If done after <code>recur_difference($p1,$p2)</code>, <code>recur_union</code> returns an empty array.  The same occurs for <code>recur_difference</code>. </p>
  
  <p>Question #1: Can anyone explain why <code>iterator_to_array</code> seems to obliterate the original DatePeriod?</p>
  
  <p>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:</p>
  
  <pre><code>$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;
  </code></pre>
  
  <p>Question #2: What is going on with the clones?</p>
  
  <p>Thanks All!</p>