确定两个日期范围是否重叠

给定两个日期范围,确定两个日期范围是否重叠的最简单或最有效的方法是什么?

例如,假设我们有由DateTime变量StartDate1EndDate1StartDate2EndDate2表示的范围。


(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都不是真的,则存在重叠 -
(如果一个范围既不完全相同,
也不完全在另一个之前,那么它们必须重叠。)

现在德摩根的一个法律说:

Not (A Or B) <=> Not A And Not B

转换为: (StartA <= EndB) and (EndA >= StartB)


注意:这包括边缘完全重叠的情况。 如果你想排除这一点,
>=运算符更改为> ,将<=更改为<


笔记2。 感谢@Baodad,看到这个博客,实际的重叠是最少的:
{ endA-startAendA - startBendB-startAendB - startB }

(StartA <= EndB) and (EndA >= StartB) (StartA <= EndB) and (StartB <= EndA)


注3。 感谢@tomosius,更短的版本显示如下:
DateRangesOverlap = max(start1, start2) < min(end1, end2)
对于什么是更长的实现,这实际上是一个语法快捷方式,其中包括额外的检查以验证开始日期是在结束日期之前还是之前。 从上面得出这个:

如果开始日期和结束日期可能无序,即,如果有可能startA > endAstartB > 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? Start A: StartB) <= (EndA < EndB? EndA: EndB)


我相信只要说两个范围重叠就足够了:

(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1)

本文的.NET时间库通过枚举PeriodRelation描述了两个时间段的关系:

// ------------------------------------------------------------------------
public enum PeriodRelation
{
    After,
    StartTouching,
    StartInside,
    InsideStartTouching,
    EnclosingStartTouching,
    Enclosing,
    EnclosingEndTouching,
    ExactMatch,
    Inside,
    InsideEndTouching,
    EndInside,
    EndTouching,
    Before,
} // enum PeriodRelation

在这里输入图像描述

链接地址: http://www.djcxy.com/p/9219.html

上一篇: Determine Whether Two Date Ranges Overlap

下一篇: Java, Calculate the number of days between two dates