给定两个日期范围,确定两个日期是否重叠的最简单或最有效的方法是什么?
例如,假设我们有由DateTime变量StartDate1到EndDate1和StartDate2到EndDate2表示的范围。
给定两个日期范围,确定两个日期是否重叠的最简单或最有效的方法是什么?
例如,假设我们有由DateTime变量StartDate1到EndDate1和StartDate2到EndDate2表示的范围。
当前回答
如果重叠本身也需要计算,可以使用以下公式:
overlap = max(0, min(EndDate1, EndDate2) - max(StartDate1, StartDate2))
if (overlap > 0) {
...
}
其他回答
我认为,在以下情况下,两个范围重叠就足够了:
(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1)
我会的
StartDate1.IsBetween(StartDate2, EndDate2) || EndDate1.IsBetween(StartDate2, EndDate2)
IsBetween是这样的
public static bool IsBetween(this DateTime value, DateTime left, DateTime right) {
return (value > left && value < right) || (value < left && value > right);
}
这是我的解决方案,当值不重叠时返回真值:
X开始1Y端1
开始2B端2
TEST1: (X <= A || X >= B)
&&
TEST2: (Y >= B || Y <= A)
&&
TEST3: (X >= B || Y <= A)
X-------------Y
A-----B
TEST1: TRUE
TEST2: TRUE
TEST3: FALSE
RESULT: FALSE
---------------------------------------
X---Y
A---B
TEST1: TRUE
TEST2: TRUE
TEST3: TRUE
RESULT: TRUE
---------------------------------------
X---Y
A---B
TEST1: TRUE
TEST2: TRUE
TEST3: TRUE
RESULT: TRUE
---------------------------------------
X----Y
A---------------B
TEST1: FALSE
TEST2: FALSE
TEST3: FALSE
RESULT: FALSE
我认为最简单的方法是比较EndDate1是否在StartDate2之前,EndDate2是否在StartDate 1之前。
当然,如果您正在考虑StartDate总是在EndDate之前的时间间隔。
由于对于不同的语言和环境有多种答案,这里有一个标准ANSISQL的答案。
在标准SQL中,它非常简单
(StartDate1, EndDate1) overlaps (StartDate2, EndDate2)
假设所有四列都是DATE或TIMESTAMP列。如果两个范围至少有一天相同(假设DATE值),则返回true
(但并非所有DBMS产品都支持此功能)
在PostgreSQL中,使用日期范围也很容易测试是否包含
daterange(StartDate1, EndDate1) @> daterange(StartDate2, EndDate2)
如果第二个范围完全包含在第一个范围中(与“重叠”不同),则上述值返回真