给定两个日期范围,确定两个日期是否重叠的最简单或最有效的方法是什么?
例如,假设我们有由DateTime变量StartDate1到EndDate1和StartDate2到EndDate2表示的范围。
给定两个日期范围,确定两个日期是否重叠的最简单或最有效的方法是什么?
例如,假设我们有由DateTime变量StartDate1到EndDate1和StartDate2到EndDate2表示的范围。
当前回答
为了涵盖PHP/LaravelCarbon包中的所有重叠情况,您可以在Charles的答案中展开逻辑,如下所示。
if ( ($startTime1->between($startTime2, $endTime2, true) || $endTime1->between($startTime2, $endTime2, true)) || (($startTime1 <= $endTime2) && ($endTime2 <= $endTime1)) ){
//Complete Overlap, Partial Left Overlap, Partial Right Overlap.
}
这将检查StartTime1是否在(StartTime2-EndTime2)范围之间,或者EndTime1是否位于(StartTime2-EndTime2的范围之间。
其余部分完全重叠,如其他答案所述。
其他回答
我会的
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);
}
只要有简单的解决方案,仅仅使用额外的包来做简单的事情可能效率不高。但是,如果您已经在项目中使用了日期fns,那么有一个名为areIntervalsOverlapping的方法也会执行同样的操作。
语法:
areIntervalsOverlapping(intervalLeft, intervalRight, [options])
例子:
// For overlapping time intervals:
areIntervalsOverlapping(
{ start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },
{ start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }
)
//=> true
本文《.NET时间段库》通过枚举PeriodRelation描述了两个时间段之间的关系:
// ------------------------------------------------------------------------
public enum PeriodRelation
{
After,
StartTouching,
StartInside,
InsideStartTouching,
EnclosingStartTouching,
Enclosing,
EnclosingEndTouching,
ExactMatch,
Inside,
InsideEndTouching,
EndInside,
EndTouching,
Before,
} // enum PeriodRelation
记住解决方案的一个简单方法是最小(结束)>最大(开始)
将问题分为几个案例,然后处理每个案例。
“两个日期范围相交”的情况有两种情况:第一个日期范围从第二个开始,或者第二个日期范围在第一个开始。