最近业务上遇到需要判断两个时间段是否存在重叠的情况,网上找了不少代码。大佬们的思路过于简洁了,有些理解不了。还只是个菜鸟码农,还是多锻炼锻炼自己的思路。
思路很简单:定义一个时间段的概念,既然是时间段就包含起始时间和终止时间这两个时间点。构造方法要保证起始时间在终止时间之前,这样才是一个有效的时间段概念。
为TimeSlot这个类定义四个比较先后顺序的方法,分别为:小于、大于、小于等于、大于等于。画张简单的时间线图理解一下就明白了。当整个时间段作为一个整体时,只有时间段小于或大于另一个时间段时,它们才没有重叠的交集。
代码如下,有什么错误还请各位看官帮忙指出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
package com.abc.common.util;
import lombok.Data;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* 日期工具类
* <p>
* 使用LocalDateTime存取或判断
* </p>
* @see java.time.LocalDateTime
* @date 2020-6-29 10:20:42
*/
@Component
public class DateUtil {
/**
* 判断两个时间段是否重叠
* @param slot1
* @param slot2
* @return
*/
public static boolean overlapped(TimeSlot slot1, TimeSlot slot2) {
TimeSlot previous, next;
previous = slot1.startTime.isBefore(slot2.startTime) ? slot1 : slot2;
next = slot2.startTime.isAfter(slot1.startTime) ? slot2 : slot1;
// 这里业务需要,允许时间点的重叠
// 例如某个时间段的起始时间:2020-06-29 00:00:00
// 和另一个时间段的终止时间:2020-06-29 00:00:00
// 它们俩可以有交点。如果不需要这种逻辑只把le改成lt
// ,ge改成gt就可
return !(le(previous, next) || ge(previous, next));
}
/**
* 构造一个时间段
* @param startTime
* @param endTime
* @return
*/
public static TimeSlot buildSlot(LocalDateTime startTime, LocalDateTime endTime) {
return new TimeSlot(startTime, endTime);
}
/**
* less equal
* 小于等于
* @param prev
* @param next
* @return
*/
private static boolean le(TimeSlot prev, TimeSlot next) {
return lt(prev, next) || next.endTime.isEqual(prev.startTime);
}
/**
* greater equal
* 大于等于
* @param prev
* @param next
* @return
*/
private static boolean ge(TimeSlot prev, TimeSlot next) {
return gt(prev, next) || prev.endTime.isEqual(next.startTime);
}
/**
* greater than
* 大于
* @param prev
* @param next
* @return
*/
private static boolean gt(TimeSlot prev, TimeSlot next) {
return prev.endTime.isBefore(next.startTime);
}
/**
* less than
* 小于
* @param prev
* @param next
* @return
*/
private static boolean lt(TimeSlot prev, TimeSlot next) {
return next.endTime.isBefore(prev.startTime);
}
/**
* 时间段类
*/
@Data
static class TimeSlot{
private LocalDateTime startTime;
private LocalDateTime endTime;
public TimeSlot(LocalDateTime startTime, LocalDateTime endTime) {
if (startTime.isAfter(endTime)) {
this .startTime = endTime;
this .endTime = startTime;
} else {
this .startTime = startTime;
this .endTime = endTime;
}
}
}
}
|
在业务代码中调用:
1
2
3
4
5
6
7
8
|
// ...
if (DateUtil.overlapped(
DateUtil.buildSlot(beginTime, endTime),
DateUtil.buildSlot(beginTime1, endTime1)
)) {
// 时间段有重叠,写下重叠情况的业务代码
}
// ...
|
当然也可以把TimeSlot这个类拎出来,那样或许更方便。
补充知识:Java计算Date类时间差的函数
我就废话不多说了,大家还是直接看代码吧~
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public static String TimeDifference( long start, long end) {
long between = end - start;
long day = between / ( 24 * 60 * 60 * 1000 );
long hour = (between / ( 60 * 60 * 1000 ) - day * 24 );
long min = ((between / ( 60 * 1000 )) - day * 24 * 60 - hour * 60 );
long s = (between / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60 );
long ms = (between - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000
- min * 60 * 1000 - s * 1000 );
String timeDifference = day + "天" + hour + "小时" + min + "分" + s + "秒" + ms
+ "毫秒" ;
return timeDifference;
}
|
以上这篇java 判断两个时间段是否重叠的案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/SakuyaM/article/details/107022611