我正在尝试在PHP中实现Martin Fowler's class model for recurring events。 DateTime和DatePeriod 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:克隆发生了什么?
全部谢谢!