前言
项目中经常会遇到判断两个时间段范围是否有交集,所以本文就记录下当时思考的过程和示例代码。
本文提供两种思路。
一、正向思维,求交集
以某个时间段为固定参考范围,然后有交集的情况共有以下四种情况分别对应图中的四种情况:
1)参考时间段 包含 比较时间段
2)参考时间段 只包含 比较时间段结束时间
3)参考时间段 只包含 比较时间段开始时间
4)比较时间段 包含 参考时间段
根据图示编写的代码示例:
/**
* 判断两个时间范围是否有交集
*
* @param dynaStartTime 比较时间段开始时间
* @param dynaEndTime 比较时间段结束时间
* @param fixedStartTime 参考时间段开始时间
* @param fixedEndTime 参考时间段结束时间
* @return
*/
public static Boolean checkTimesHasOverlap(Date dynaStartTime, Date dynaEndTime, Date fixedStartTime, Date fixedEndTime) {
if(dynaStartTime.getTime() >= fixedStartTime.getTime() && dynaEndTime.getTime() <= fixedEndTime.getTime()){
// 参考时间段 包含 比较时间段
return true;
} else if (dynaStartTime.getTime() <= fixedStartTime.getTime() && (dynaEndTime.getTime() >= fixedStartTime.getTime() && dynaEndTime.getTime() <= fixedEndTime.getTime())) {
// 参考时间段 只包含 比较时间段结束时间
return true;
} else if (dynaStartTime.getTime() >= fixedStartTime.getTime() && dynaStartTime.getTime() <= fixedEndTime.getTime() && fixedEndTime.getTime() >= fixedEndTime.getTime()) {
// 参考时间段 只包含 比较时间段开始时间
return true;
} else if (dynaStartTime.getTime() <= fixedStartTime.getTime() && fixedEndTime.getTime() >= fixedEndTime.getTime()) {
// 比较时间段 包含 参考时间段
return true;
}else {
return false;
}
}
这种方式是最直接、直观的方式,如果需要求出交集时间段,也可使用这种方式。
如果只需要判断是否有交集,其实代码可以优化合并一下的,具体示例:
/**
* 判断两个时间范围是否有交集
*
* @param dynaStartTime 比较时间段开始时间
* @param dynaEndTime 比较时间段结束时间
* @param fixedStartTime 参考时间段开始时间
* @param fixedEndTime 参考时间段结束时间
* @return
*/
public static Boolean checkTimesHasOverlap(Date dynaStartTime, Date dynaEndTime, Date fixedStartTime, Date fixedEndTime) {
if (dynaStartTime.getTime() <= fixedStartTime.getTime() && dynaEndTime.getTime() > fixedStartTime.getTime()) {
return true;
} else if (dynaStartTime.getTime() >= fixedStartTime.getTime() && dynaStartTime.getTime() < fixedEndTime.getTime()) {
return true;
} else {
return false;
}
}
这样代码就比较简单了,但是理解可能相对吃力。
二、逆向思维,取反
首先求出两时间段没有交集的两种情况和图示对应,然后取反:
1) 比较时间段的结束时间在参考时间段的开始时间之前
2) 比较时间段的开始时间在参考时间段的结束时间之后
示例代码:
/**
* 判断两个时间范围是否有交集
*
* @param dynaStartTime 比较时间段开始时间
* @param dynaEndTime 比较时间段结束时间
* @param fixedStartTime 参考时间段开始时间
* @param fixedEndTime 参考时间段结束时间
* @return
*/
public static Boolean checkTimesHasOverlap(Date dynaStartTime, Date dynaEndTime, Date fixedStartTime, Date fixedEndTime) {
return !(dynaEndTime.getTime() < fixedStartTime.getTime() || dynaStartTime.getTime() > fixedEndTime.getTime());
}
这样代码即简单又很好理解。