我有几个日期范围,形式为DateTime $begin, DateTime $end
. 这些范围可以以各种可能的方式重叠:
|-------|
|=======|
|------|
|======|
|------------|
|=======|
|---|
等等
我要做的是获取DateInterval
第一个开始到最新一个结束(在上述情况下为第四个)之间的这些范围的长度(以秒或 为单位),不包括任何范围未涵盖的区域。
只有两个范围没有问题,但我不知道如何扩展它以处理两个以上。
编辑:
class Range {
public DateTime $begin;
public DateTime $end;
}
$ranges = getRanges(); # function that returns array of Range objects
function getActiveHours($_ranges = array()) {
$sum = 0;
# this is the function I'd like to have
return $sum;
}
仅对于两个范围,我有一个返回DateInterval
对象的函数:
function addTimeRanges(DateTime $b1, DateTime $e1, DateTime $b2, DateTime $e2) {
$res = null;
if ($e1 < $b2 || $e2 < $b1) { # separate ranges
$r1 = $b1->diff($e1);
$r2 = $b2->diff($e2);
$res = addIntervals($r1, $r2);
} else if ($b1 <= $b2 && $e1 >= $e2) { # first range includes second
$res = $b1->diff($e1);
} else if ($b1 > $b2 && $e1 < $e2) { # second range includes first
$res = $b2->diff($e2);
} else if ($b1 < $b2 && $e1 <= $e2 && $b2 <= $e1) { # partial intersection
$res = $b1->diff($e2);
} else if ($b2 < $b1 && $e2 <= $e1 && $b1 <= $e2) { # partial intersection
$res = $b2->diff($e1);
}
return $res;
}
whereaddIntervals
是一个将两个DateInterval
对象之和作为另一个DateInterval
对象返回的函数。
这是一些基本版本,在我的生产代码中我使用了很多其他不相关的东西。
为了简化,假设我们只有时间部分DateTime
:('06:00:00' to '08:00:00'), ('07:00:00' to '09:00:00'), ('06 :00:00', '08:00:00'), ('11:00:00' to '12:00:00') (会有很多这样的范围)。我现在想要的结果是 4 小时(从 6:00 到 9:00 + 从 11:00 到 12:00)。