DatePeriod的时态表达式?

时间:2009-09-14 17:47:34

标签: datetime php-5.3

我正在尝试在PHP中实现Martin Fowler's class model for recurring eventsDateTimeDatePeriod PHP对象看起来很适合处理时态表达式。问题是我需要能够对DatePeriods执行UNION,INTERSECT和DIFFERENCE操作,这样我就可以计算“除了偶数日期之外的每个星期二”这样的表达式。这个例子需要“每周二”DatePeriod和“偶数日期”DatePeriod的区别。

DatePeriod是可迭代的,但array_intersect()array_diff()等标准数组处理函数无法访问它。 (我希望!)所以我尝试将DatePeriod更改为$ap=array_to_iterator($dp)的数组。这主要按预期工作,除了DatePeriod包含的DateTime对象没有__toString()方法,这是许多数组函数所需要的。

我最近的尝试最接近:

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;

不幸的是,似乎DatePeriods $ p1和$ p2在处理期间被破坏了。如果我先recur_union($p1,$p2),我会得到一个有效的结果。如果在recur_difference($p1,$p2)之后完成,recur_union将返回一个空数组。 recur_difference也是如此。

问题#1:有人可以解释为什么iterator_to_array似乎要删除原来的DatePeriod吗?

由于我的DatePeriods遭到破坏,我以为我会尝试克隆它们。但以下原因导致IE8显示“无法显示网页”消息而FF3.5无效:

$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;

问题2:克隆发生了什么?

全部谢谢!

1 个答案:

答案 0 :(得分:1)

去年我有一个类似的问题,虽然对我来说,我很难将它与持久层相关联。对于应用程序层,一种方法是将作业分成一组处理集合操作(​​交集,并集,差异)的类和处理“时间表达式”(每月,每月的最后一天)的一组。然后可以将时间类组合在一起以生成任意复杂的日期条件。

我已经撰写过有关此主题的文章,并提供了示例课程herehere