给定两个日期范围,确定两个日期范围是否重叠的最简单或最有效的方法是什么?
举个例子,假设我们有由日期时间变量 StartDate1
到 EndDate1
和 StartDate2
到 EndDate2
.
最佳答案
(StartA <= EndB)和(EndA >= StartB)
证明:
令 ConditionA 表示 DateRange A 完全在 DateRange B 之后
_ |---- DateRange A ------|
|---Date Range B -----| _
(如果StartA > EndB
则为真)
让 ConditionB 表示 DateRange A 完全早于 DateRange B
|---- DateRange A -----| _
_ |---Date Range B ----|
(如果EndA < StartB
则为真)
如果 A 和 B 都不为真,则存在重叠 -
(如果一个范围不完全在另一个范围之后,
也不完全先于另一个,
那么它们必须重叠。)
现在是 De Morgan's laws 之一说:
Not (A Or B)
<=> Not A And Not B
这意味着:(StartA <= EndB) and (EndA >= StartB)
注意:这包括边缘完全重叠的情况。如果您想排除它,
更改 >=
运营商至>
,和<=
至<
注2。感谢@Baodad,请参阅this blog ,实际重叠最少:
{ endA-startA
, endA - startB
, endB-startA
, endB - startB
}
(StartA <= EndB) and (EndA >= StartB)
(StartA <= EndB) and (StartB <= EndA)
注3。感谢@tomosius,较短的版本如下:
DateRangesOverlap = max(start1, start2) < min(end1, end2)
这实际上是较长实现的语法快捷方式,其中包括额外的检查以验证开始日期是否等于或早于结束日期。从上面得出:
如果开始日期和结束日期可能无序,即,如果可能 startA > endA
或startB > endB
,那么你还必须检查它们是否按顺序排列,这意味着你必须添加两个额外的有效性规则:
(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)
或:
(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)
或者,
(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))
或:
(Max(StartA, StartB) <= Min(EndA, EndB)
但要实现Min()
和Max()
,你必须编码(为了简洁,使用 C 三进制):
((StartA > StartB) ? StartA : StartB) <= ((EndA < EndB) ? EndA : EndB)
关于datetime - 确定两个日期范围是否重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50107071/