временные выражения с DatePeriod? - PullRequest
2 голосов
/ 14 сентября 2009

Я пытаюсь реализовать модель классов Мартина Фаулера для повторяющихся событий в PHP. Объекты DateTime и DatePeriod PHP выглядят так, как будто они хорошо подходят для работы с временными выражениями. Проблема в том, что мне нужно иметь возможность выполнять операции UNION, INTERSECT и DIFFERENCE над DatePeriods, чтобы я мог вычислять выражения типа «каждый вторник, кроме четных дат». В этом примере потребуется разность DatePeriod «каждый вторник» и DatePeriod «четная дата».

DatePeriod является итеративным, но он не доступен для стандартных функций обработки массивов, таких как array_intersect() и array_diff(). (Я хочу!) Поэтому я попытался изменить DatePeriod на массив с $ap=array_to_iterator($dp). Это работает в основном так, как ожидалось, за исключением того, что объекты DateTime, содержащиеся в DatePeriod, не имеют метода __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 Ответ

1 голос
/ 07 февраля 2010

У меня был похожий вопрос в прошлом году, хотя у меня возникли трудности с привязкой его к постоянному слою. Для прикладного уровня один из подходов состоит в том, чтобы разделить задание на один набор классов, который обрабатывает операции над множествами (пересечение, объединение, различие), и один, который обрабатывает «временные выражения» (каждый месяц, последний день месяца). Затем временные классы могут быть скомпонованы для создания произвольно сложных условий дат.

Я написал об этой теме и предоставил примеры классов здесь и здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...