我有一系列日期如下:
[Room 01 - DBL] => Array
(
[0] => Mon 23-06-2014
[1] => Tue 24-06-2014
[2] => Wed 25-06-2014
[3] => Sat 28-06-2014
[4] => Sun 29-06-2014
)
[Room 02 - TWN] => Array
(
[0] => Tue 24-06-2014
[1] => Wed 25-06-2014
[2] => Sat 28-06-2014
[3] => Sun 29-06-2014
)
你可以看到这两个房间都没有星期四或星期五的日期。我希望能够为每组日期创建日期范围(或者不是DateTime Interval对象 - 不要介意)。所以02号房间 - TWN应该给我两个日期 - 一个用于星期二 - 星期三,另一个用于星期六 - 星期日。我该怎么做?我知道如何使用数组中的第一个和最后一个项来创建单个日期时间段但不知道如何检测是否存在间隙......
答案 0 :(得分:1)
我不太清楚你想要完成什么。无论如何,在一般情况下,你可以做这样的事情。
这个想法是运行整个项目数组,如果“下一个”项目与您已有的候选区间相邻,则延长时间间隔。否则,候选区间变为独立区间,而未通过检查的项目会产生新的候选区间。
你需要两个函数:一个给定两个项目,返回它们是连续的是真还是假;另外,给定两个项目,返回一个“间隔”,将这两个项目作为极值。
空$items
将返回一个空的间隔。
function build_intervals($items, $is_contiguous, $make_interval) {
$intervals = array();
$end = false;
foreach ($items as $item) {
if (false === $end) {
$begin = $item;
$end = $item;
continue;
}
if ($is_contiguous($end, $item)) {
$end = $item;
continue;
}
$intervals[] = $make_interval($begin, $end);
$begin = $item;
$end = $item;
}
if (false !== $end) {
$intervals[] = $make_interval($begin, $end);
}
return $intervals;
}
对于数字,您可以使用
$interv = build_intervals(
array( 1, 2, 3, 5, 6, 9, 10, 11, 13, 17, 18 ),
function($a, $b) { return ($b - $a) <= 1; },
function($a, $b) { return "{$a}..{$b}"; }
);
print_r($interv);
返回
Array
(
[0] => 1..3
[1] => 5..6
[2] => 9..11
[3] => 13..13
[4] => 17..18
)
使用日期,您可以将其保留为DateTime
和DateTimeIntervals
。如果使用时间戳,则必须提供对时间戳有效的连续条件。如果您有两个时间戳在第二天的午夜之前和之后,这可能会很尴尬。可以肯定的是,你应该总是在中午左右(即给定两个日期,在中午获得那些日期的时间戳。如果他们相隔不到36小时,他们就是两个相邻的天。
function($a, $b) {
$a_ts = strtotime("{$a} 12:00:00");
$b_ts = strtotime("{$b} 12:00:00");
return ($b - $a) <= (36 * 60 * 60);
},