关于php:确定两个时间范围是否在任何点重叠

Determining if two time ranges overlap at any point

本问题已经有最佳答案,请猛点这里访问。

0

我正在努力研究PHP中的两个时间范围是否重叠。我一直在参考确定两个日期范围是否在我最初的尝试中重叠,但是,它不匹配所有的情况。如果一个时间范围嵌套在另一个时间范围的开始时间和结束时间之间,则不匹配。如果它与班次的开始或结束重叠,或者班次完全匹配,它将按预期工作。

看看我所说的图片:

enter image description here

基本上,我试图隐藏任何橙色移位,如果它们在任何地方重叠任何红色移位。下面是我试图用来实现这一点的代码的相关部分。

1
2
3
if(($red['start'] <= $orange['end']) && ($red['end'] >= $orange['start'])) {
    //Conflict handling
}

变量的值是unix时间戳。从逻辑上分析这些数字,我理解了上面的语句为什么会失败。很明显,我可以用更多的逻辑方法来判断一个转变是否属于另一个转变(这是我可能需要做的),但我希望有一个更普遍的结果。

编辑:添加每个块的开始和结束时间的值。我同意我所拥有的应该有效。事实上,这不是我的问题所在。我可能忽略了一些愚蠢的东西。

1
2
3
4
5
orange-start = 1352899800
orange-end = 1352907000

red-start = 1352923200
red-end = 1352926200

因此,我的逻辑是:

2

所以接下来,第一次比较失败了。

编辑2:看起来我的逻辑是合理的(我认为是这样),我的问题是与Unix时间戳不匹配显示的实际时间有关。我感谢那些和我一起工作的人,并帮助我发现这就是问题所在。我希望我能接受安德烈和杰森的答案。


如果您有两个范围[b1, e1][b2, e2](其中已经确定b1 < e1b2 < e2),则通过以下逻辑表达式检测重叠

2

可以重写为

1
e2 >= b1 and e1 >= b2

在你的语法中

1
2
3
if(($orange['end'] >= $red['start']) && ($red['end'] >= $orange['start'])) {
   //Conflict handling
}

也就是说,你答对了。为什么你声称"从逻辑上分析数字,我理解为什么上面的陈述失败了。"我不清楚。到底什么失败了?(我不知道为什么每个人都会做出荒谬的"过度设计"的检查,并进行两次以上的比较。)

当然,您必须决定触摸范围是否被认为是重叠的,并相应地调整比较的严格性。

P.S.您在编辑中提供的样本范围没有重叠,您的比较正确地将其识别为无冲突情况。也就是说,一切都按原样工作。你在哪里看到这个问题?


逻辑是正确的。您为$red$orange提供的时间戳没有重叠。

给定正确的值(反映屏幕截图),确实会发现重叠:

1
2
3
4
5
6
7
8
9
10
11
12
13
function show_date($value, $key) {
    echo $key, ': ', date('r', $value), PHP_EOL;
}

$red = array('start' => strtotime('today, 2pm'), 'end' => strtotime('today, 2:45pm'));
$orange = array('start' => strtotime('today, 1:30pm'), 'end' => strtotime('today, 4pm'));

array_walk($red, 'show_date');
array_walk($orange, 'show_date');

if (($red['start'] <= $orange['end']) && ($red['end'] >= $orange['start'])) {
    echo 'Conflict handling';
}

我猜你有时区转换问题。


您需要检查您的"红色"任务是否在"橙色"任务的开始和结束之间开始或结束。像这样,您应该检测到每个"橙色"任务与"红色"任务重叠。

1
2
3
4
if((($red['start'] <= $orange['end']) && ($red['start'] >= $orange['start'])) ||
   (($red['end'] <= $orange['end']) && ($red['end'] >= $orange['start'])) ) {
    //Conflict handling
}

编辑:正如安德烈所说,这是一种过度杀戮,你可以用更少的检查做得更好。


1
2
3
4
5
6
7
8
9
if ((($red['start'] <= $orange['end']) && ($red['start'] >= $orange['start']))
    || (($red['end'] <= $orange['end']) && ($red['end'] >= $orange['start']))
    || (($red['start'] >= $orange['start']) && ($red['end'] >= $orange['end']))
   ) {
 // conflict happens if Red starts sometime between Orange start and end
 //               or if Red ends sometime between Orange start and end
 //               or if Red starts before Orange starts and ends after Orange ends

}