确定两个日期范围是否重叠 [英] Determine Whether Two Date Ranges Overlap
问题描述
给定两个日期范围,确定两个日期范围是否重叠的最简单或最有效的方法是什么?
Given two date ranges, what is the simplest or most efficient way to determine whether the two date ranges overlap?
举个例子,假设我们有由 DateTime 变量表示的范围 StartDate1
到 EndDate1
and StartDate2
到 <代码>EndDate2.
As an example, suppose we have ranges denoted by DateTime variables StartDate1
to EndDate1
and StartDate2
to EndDate2
.
推荐答案
(StartA <= EndB) and (EndA >= StartB)
证明:
让 ConditionA 表示 DateRange A 完全在 DateRange B 之后
Proof:
Let ConditionA Mean that DateRange A Completely After DateRange B
_ |---- DateRange A ------|
|---Date Range B -----| _
(如果 StartA > EndB
为真)
令 ConditionB 表示 DateRange A 完全在 DateRange B 之前
Let ConditionB Mean that DateRange A is Completely Before DateRange B
|---- DateRange A -----| _
_ |---Date Range B ----|
(如果 EndA
如果 A 和 B 都不为真,则存在重叠 -
(如果一个范围既不完全在另一个范围之后,
也不完全在另一个之前,那么它们必须重叠.)
Then Overlap exists if Neither A Nor B is true -
(If one range is neither completely after the other,
nor completely before the other,
then they must overlap.)
现在德摩根定律之一说:
不是(A 或 B)
<=>不是A也不是B
翻译成:(StartA <= EndB) and (EndA >= StartB)
注意:这包括边缘完全重叠的情况.如果你想排除那个,
将 >=
运算符更改为 >
,并将 <=
更改为 <
NOTE: This includes conditions where the edges overlap exactly. If you wish to exclude that,
change the >=
operators to >
, and <=
to <
注意2.感谢@Baodad,见这篇博客,实际重叠的是最少的:
{ endA-startA
, endA - startB
, endB-startA
, endB - startB
}
NOTE2. Thanks to @Baodad, see this blog, the actual overlap is least of:
{ endA-startA
, endA - startB
, endB-startA
, endB - startB
}
(StartA <= EndB) 和 (EndA >= StartB)
(StartA <= EndB) 和 (StartB <= EndA)
注意3.感谢@tomosius,一个更短的版本如下:DateRangesOverlap = max(start1, start2)
这实际上是更长实现的语法快捷方式,其中包括额外的检查以验证开始日期是否在 endDates 上或之前.从上面推导出来:
NOTE3. Thanks to @tomosius, a shorter version reads:
DateRangesOverlap = max(start1, start2) < min(end1, end2)
This is actually a syntactical shortcut for what is a longer implementation, which includes extra checks to verify that the start dates are on or before the endDates. Deriving this from above:
如果开始和结束日期可能乱序,即,如果 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)
If start and end dates can be out of order, i.e., if it is possible that startA > endA
or startB > endB
, then you also have to check that they are in order, so that means you have to add two additional validity rules:
(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)
但是要实现Min()
和Max()
,你必须编码,(为了简洁,使用C三元),:(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)
But to implement Min()
and Max()
, you have to code, (using C ternary for terseness),:
(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)
这篇关于确定两个日期范围是否重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!