确定两个日期范围是否重叠 [英] Determine Whether Two Date Ranges Overlap

查看:39
本文介绍了确定两个日期范围是否重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Given two date ranges, what is the simplest or most efficient way to determine whether the two date ranges overlap?

举个例子,假设我们有由 DateTime 变量表示的范围 StartDate1EndDate1 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 >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)

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆