Java日期时间API系列37-----时间段是否有重叠(交集)的计算方法
在日程安排或预约排期等场景中,经常会需要对比2个或多个时间段是重叠的功能,我经过整理和验证,发现了下面的算法比较好一些,分享一下。
1.只有2个时间段的情况
例如:存在区间A
、区间B,重叠的情况很多,但
不重叠的情况只有2种,A在B前或者B在A前。如图:
得出,不重叠算法:A.end< B.start || A.start > B.end
那么重叠的算法对上面取反就可以了:! (A.end< B.start || A.start > B.end)
Java算法实现:! (A.end< B.start || A.start > B.end) 这里为了通用性,将时间类统一通过getTime()方法,转换为时间戳对比。
/**
* 判断2个时间段是否有重叠(交集)
* @param startDate1 时间段1开始时间戳
* @param endDate1 时间段1结束时间戳
* @param startDate2 时间段2开始时间戳
* @param endDate2 时间段2结束时间戳
* @param isStrict 是否严格重叠,true 严格,没有任何相交或相等;false 不严格,可以首尾相等,比如2021/5/29-2021/5/31和2021/5/31-2021/6/1,不重叠。
* @return 返回是否重叠
*/
public static boolean isOverlap(long startDate1, long endDate1, long startDate2, long endDate2, boolean isStrict){
if(endDate1<startDate1){
throw new DateTimeException("endDate1不能小于startDate1");
}
if(endDate2<startDate2){
throw new DateTimeException("endDate2不能小于startDate2");
}
if(isStrict){
if(! (endDate1<startDate2 || startDate1>endDate2)){
return true;
}
}else{
if(! (endDate1<=startDate2 || startDate1>=endDate2)){
return true;
}
}
return false;
} /**
* 判断2个时间段是否有重叠(交集)
* @param startDate1 时间段1开始时间
* @param endDate1 时间段1结束时间
* @param startDate2 时间段2开始时间
* @param endDate2 时间段2结束时间
* @param isStrict 是否严格重叠,true 严格,没有任何相交或相等;false 不严格,可以首尾相等,比如2021-05-29到2021-05-31和2021-05-31到2021-06-01,不重叠。
* @return 返回是否重叠
*/
public static boolean isOverlap(Date startDate1, Date endDate1, Date startDate2, Date endDate2, boolean isStrict){
Objects.requireNonNull(startDate1, "startDate1");
Objects.requireNonNull(endDate1, "endDate1");
Objects.requireNonNull(startDate2, "startDate2");
Objects.requireNonNull(endDate2, "endDate2");
return isOverlap(startDate1.getTime(), endDate1.getTime(), startDate2.getTime(), endDate2.getTime(), isStrict);
}
2.大于2个时间段的情况
如果大于2个时间段,需要相互都比较一次,比较麻烦,可以先根据开始时间排序,然后一次遍历对比:
由上面2个时间段算法得出,有序情况下,不重叠算法:A.end< B.start
那么重叠的算法对上面取反就可以了:! (A.end< B.start)
Java算法实现:先根据开始时间排序,遍历对比,! (A.end< B.start)
/**
* 时间段
*
*@author xkzhangsan
*/
public class TimePair { public TimePair(long start, long end) {
if(end<start){
throw new DateTimeException("end不能小于start");
}
this.start = start;
this.end = end;
} private long start; private long end; public long getStart() {
return start;
} public void setStart(long start) {
this.start = start;
} public long getEnd() {
return end;
} public void setEnd(long end) {
this.end = end;
} } /**
* 判断多个时间段是否有重叠(交集)
* @param timePairs 时间段数组
* @param isStrict 是否严格重叠,true 严格,没有任何相交或相等;false 不严格,可以首尾相等,比如2021-05-29到2021-05-31和2021-05-31到2021-06-01,不重叠。
* @return 返回是否重叠
*/
public static boolean isOverlap(TimePair[] timePairs, boolean isStrict){
if(timePairs==null || timePairs.length==0){
throw new DateTimeException("timePairs不能为空");
} Arrays.sort(timePairs, Comparator.comparingLong(TimePair::getStart)); for(int i=1;i<timePairs.length;i++){
if(isStrict){
if(! (timePairs[i-1].getEnd()<timePairs[i].getStart())){
return true;
}
}else{
if(! (timePairs[i-1].getEnd()<=timePairs[i].getStart())){
return true;
}
}
}
return false;
} /**
* 判断多个时间段是否有重叠(交集)
* @param timePairList 时间段列表
* @param isStrict 是否严格重叠,true 严格,没有任何相交或相等;false 不严格,可以首尾相等,比如2021-05-29到2021-05-31和2021-05-31到2021-06-01,不重叠。
* @return 返回是否重叠
*/
public static boolean isOverlap(List<TimePair> timePairList, boolean isStrict){
if(CollectionUtil.isEmpty(timePairList)){
throw new DateTimeException("timePairList不能为空");
}
TimePair[] timePairs = new TimePair[timePairList.size()];
timePairList.toArray(timePairs);
return isOverlap(timePairs, isStrict);
}
可以看出多个时间段的算法也适用于2个时间段,2个时间段只是其中的一个特例。
源代码地址:https://github.com/xkzhangsan/xk-time
参考:https://blog.csdn.net/Mister_SNAIL/article/details/77860240
Java日期时间API系列37-----时间段是否有重叠(交集)的计算方法的更多相关文章
- Java日期时间API系列19-----Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格式化和时区转换等。
通过Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类中时间范围示意图:可以很清晰的看出ZonedDateTime相当于LocalDateTime+ZoneI ...
- Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析
目录 0.前言 1.TemporalAccessor源码 2.Temporal源码 3.TemporalAdjuster源码 4.ChronoLocalDate源码 5.LocalDate源码 6.总 ...
- Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate
通过Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的优点,java8具有很多优点,现在网上查到的农历转换工具类都是基于jdk7及以前的类写的,下面使用ja ...
- Java日期时间API系列12-----Jdk8中java.time包中的新的日期时间API类,日期格式化,常用日期格式大全
通过Java日期时间API系列10-----Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter, 可以看出java8的DateTimeFormatter完美解决 ...
- Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类
因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题,2005年,Stephen Colebourne创建了Joda-Time库,作为替代的日期和时间API.Stephen向JCP提交了 ...
- Java日期时间API系列13-----Jdk8中java.time包中的新的日期时间API类,时间类转换,Date转LocalDateTime,LocalDateTime转Date等
从前面的系列博客中可以看出Jdk8中java.time包中的新的日期时间API类设计的很好,但Date由于使用仍非常广泛,这就涉及到Date转LocalDateTime,LocalDateTime转D ...
- Java日期时间API系列3-----Jdk7及以前的日期时间类的不方便使用问题
使用Java日期时间类,每个人都很熟悉每个项目中必不可少的工具类就是dateutil,包含各种日期计算,格式化等处理,而且常常会遇到找不到可用的处理方法,需要自己新增方法,处理过程很复杂. 1.Dat ...
- Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的特点
1.不变性 新的日期/时间API中,所有的类都是不可变的,这对多线程环境有好处. 比如:LocalDateTime 2.关注点分离 新的API将人可读的日期时间和机器时间(unix timestamp ...
- Java日期时间API系列10-----Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter
1.DateTimeFormatter final修饰,线程安全,用于打印和解析日期-时间对象的格式化程序. 创建DateTimeFormatter: DateTimeFormatter dateTi ...
- Java日期时间API系列1-----Jdk7及以前的日期时间类
先看一个简单的图: 主要的类有: Date类负责时间的表示,在计算机中,时间的表示是一个较大的概念,现有的系统基本都是利用从1970.1.1 00:00:00 到当前时间的毫秒数进行计时,这个时间称为 ...
随机推荐
- python selenium元素定位
1.ID元素定位基于元素属性中的id的值来进行定位,id是一个标签的唯一属性值可以通过id属性来唯一定位一个元素,是首选的元素定位方式,动态ID不做考虑.driver .find_element_by ...
- 【Java】MultiThread 多线程 Re01
学习参考: https://www.bilibili.com/video/BV1ut411T7Yg 一.线程创建的四种方式: 1.集成线程类 /** * 使用匿名内部类实现子线程类,重写Run方法 * ...
- 【JavaScript】Jquery事件绑定问题
我们所知道的选择器方式,其中有一种方式是属性选择器: <div style="display: flex; justify-content: space-between;"& ...
- 深度学习的始祖框架,grandfather级别的框架 —— Theano —— 示例代码学习(5)
代码1:(求雅可比矩阵, jacobian矩阵求解) import theano from theano import tensor # Creating a vector x = tensor.dv ...
- 中国2023年GDP增速5.2%
在中美贸易战和三年全球疫情的大背景下,我国的经济依旧保持强有力的增速,这表明了经济发展不断转好,一切恢复到疫情和贸易战之前也是有待期望的.
- 国内网友搭建的 Huggingface 镜像站 —— https://hf-mirror.com/
huggingface是什么这里不作解释. hugggingface的网站访问同Google一样,不能直接通过浏览器访问,需要科学的方式才可以,这里假设大家是知道如何访问Google的: huggin ...
- 【转载】 模仿学习:在线模仿学习与离线模仿学习 ———— Imitate with Caution: Offline and Online Imitation
网上闲逛找到的一篇文章,介绍模仿学习的,题目: Imitate with Caution: Offline and Online Imitation 之所以转载这个文章是因为这个文章还是蛮浅显易懂的, ...
- 新晋 Committer!来自复旦大学的帅哥一枚
点亮Star️ · 支持我们 https://github.com/apache/dolphinscheduler 最近,社区星力量又迎来一位新晋 Committer,这次是来自复旦大学研究生在读的王 ...
- Apache SeaTunnel k8s 集群模式 Zeta 引擎部署指南
SeaTunnel提供了一种运行Zeta引擎(cluster-mode)的方法,可以让Kubernetes在本地运行Zeta引擎,实现更高效的应用程序部署和管理.在本文中,我们将探索SeaTunnel ...
- 在一串字符串中Java使用正则匹配电话号码的方法
1.使用正则表达式来匹配电话号码 在Java中,使用正则表达式匹配电话号码是一个常见的需求.电话号码的格式可能因国家/地区而异,但一个典型的格式可能是这样的:(123) 456-7890.在这个例子中 ...