如何在PHP中查找重叠的日期区间?

9
如果我有两个日期范围(例如5月1日至5月31日和5月23日至6月5日),那么在PHP中找到这两个期间重叠的天数的最佳方法是什么(因此它将返回9)?是否有一种使用DatePeriod对象来实现这一点的方法?
编辑以澄清我的问题:基本上,我想要一个函数,给定任何两个日期范围,都将返回两个日期范围之间共同的天数。如果存在重叠,则返回重叠天数,否则返回0。我认为可以通过为每个范围创建一个日期数组,循环遍历它们以查找相同的日期,并使用变量来计算匹配数量来完成此操作 - 但我正在寻找更优雅的解决方案。

抱歉,我应该更清楚。我想我可能可以为每个范围制作一个日期数组,循环遍历它们以查找相同的日期,并使用变量来计算匹配次数。如果使用DatePeriod有一种更基本的方法来做到这一点,那么似乎这可能过于复杂。我知道您可以使用DateTime->diff计算两个日期之间的差异,因此我认为DatePeriod可能有类似的功能,但是在Google上我没有太多好运。也许像$dateperiod->diff($dateperiod2)这样的东西。 - Dustin
好的,这个问题已经被投票下降并关闭了,这没关系。但是我该怎么做才能停止被投票下降呢? - Dustin
2个回答

40

感谢 @phpisuber01 和 Determine Whether Two Date Ranges Overlap 在这里提供基本逻辑。这四个变量需要是DateTime对象:

function datesOverlap($start_one,$end_one,$start_two,$end_two) {

   if($start_one <= $end_two && $end_one >= $start_two) { //If the dates overlap
        return min($end_one,$end_two)->diff(max($start_two,$start_one))->days + 1; //return how many days overlap
   }

   return 0; //Return 0 if there is no overlap
}

7
为了完整起见,也可以反过来使用: 如果 (($start_one <= $end_two && $end_one >= $start_two) || ($start_two <= $end_one && $end_two >= $start_one) ){ ... } 注意:此处为计算机代码,翻译时应保留原始语法和格式。 - eddy147
1
以上评论是不正确的,您不需要两个条件。 - morphles

1

虽然没有任何真实的信息作为基础,但这里有一个使用DateTime对象计算天数差异的基本示例。

$datetime1 = new DateTime('2013-05-23');
$datetime2 = new DateTime('2013-05-31');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days'); //returns 8 days

我假设你知道如何将你的字符串转换成可用的时间戳/格式。


1
是的,我已经知道如何比较两个日期了。我想要的是比较两个日期范围或DatePeriods的东西。也就是说,$dateperiod1与$dateperiod2重叠了多少? - Dustin
@Dustin,你需要做的就是获取第一个范围内的最后日期和最后一个范围内的第一个日期进行比较。完成! - phpisuber01
谢谢。在我给出的例子中这个方法是有效的,但是我应该也提到其中一个范围是预设的,而另一个范围是由用户设置的,所以可能根本没有重叠。在这种情况下,将一个范围中的最后日期与另一个范围中的第一个日期进行比较,会得到一个正数,而实际上应该返回0。 - Dustin
@Dustin 如果没有所有信息,就没有人能给你答案。您应该使用所有这些详细信息和您的尝试更新您的问题。一些简单的逻辑将解决您可能对虚幻日期间隔感到的任何担忧。 - phpisuber01
是的,我不知道为什么今天写问题遇到了这么多麻烦。我想可能是因为实际答案与我预期的不同,但即便如此,我也很抱歉没有提供足够详细和清晰的信息。我认为您的提示已经让我走上了解决问题的正确道路,所以感谢您的耐心。一旦我解决了问题,我将编辑我的问题并发布我的解决方案。 - Dustin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接