给定两个日期范围,确定两个日期范围是否重叠的最简单或最有效的方法是什么?
例如,假设我们有由 DateTime 变量StartDate1toEndDate1 和 StartDate2to表示的范围EndDate2。
StartDate1
EndDate1
StartDate2
EndDate2
(StartA <= EndB) 和 (EndA >= StartB)
证明: 令 ConditionA 表示 DateRange A 完全在 DateRange B 之后
_ |---- DateRange A ------| |---Date Range B -----| _
(如果 为真StartA > EndB)
StartA > EndB
让 ConditionB 表示 DateRange A 完全在 DateRange B 之前
|---- DateRange A -----| _ _ |---Date Range B ----|
(如果 为真EndA < StartB)
EndA < StartB
如果 A 和 B 都不为真,则存在重叠 - (如果一个范围既不完全在另一个之后, 也不完全在另一个之前,那么它们必须重叠。)
现在,德摩根的一条定律说:
Not (A Or B)` <=> `Not A And Not B
翻译为:(StartA <= EndB) and (EndA >= StartB)
(StartA <= EndB) and (EndA >= StartB)
注意:这包括边缘完全重叠的情况。如果您希望排除它,请将运算符 更改 为, 和>=``>``<=``<
>=``>``<=``<
笔记2。实际重叠最少: { endA-startA, endA - startB, endB-startA, endB - startB}
endA-startA
endA - startB
endB-startA
endB - startB
(StartA <= EndB) and (EndA >= StartB)` `(StartA <= EndB) and (StartB <= EndA)
注3,一个较短的版本如下: DateRangesOverlap = max(start1, start2) < min(end1, end2) 这实际上是一个较长实现的语法快捷方式,其中包括额外的检查以验证开始日期是否在结束日期之前或之前。从上面得出:
DateRangesOverlap = max(start1, start2) < min(end1, end2)
如果开始日期和结束日期可能是无序的,即,如果可能是startA > endAor startB > endB,那么您还必须检查它们是否有序,这意味着您必须添加两个额外的有效性规则: (StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB) or: (StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB) or, (StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB)) or: (Max(StartA, StartB) <= Min(EndA, EndB)
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()and Max(),您必须编写代码(为了简洁起见,使用 C 三元): (StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)
Min()
Max()
(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)