1、逻辑公式
时间段1:start1(开始时间),end1(结束时间)
时间段2:start2(开始时间),end2(结束时间)
重叠条件为:start1 <= end2 && end1 >= start2。
2、java实现
工具方法
/**
* 判断时间是否重叠
* true重叠。false不重叠
*
* @param start1
* @param end1
* @param start2
* @param end2
* @param isStrict 是否严格遵守不能重叠,例如如果为true 那么8:00-8:30 和8:30-9:00 时间段比较为true
* @methodName: isOverlapLocalTime
* @return: boolean
* @date: 2023/8/10
**/
public static boolean isOverlapLocalTime(LocalTime start1, LocalTime end1, LocalTime start2, LocalTime end2, boolean isStrict) {
if (start1.isAfter(end1) || start2.isAfter(end2)) {
throw new DateTimeException("endDate不能小于startDate");
}
if (isStrict) {
if (start1.compareTo(end2) <= 0 && end1.compareTo(start2) >= 0) {
//重叠
return true;
}
//不重叠
return false;
}
if (start1.compareTo(end2) < 0 && end1.compareTo(start2) > 0) {
//重叠
return true;
}
//不重叠
return false;
}
测试
/**
* 判断时间是否重叠
*
* @methodName: isOverlap
* @return: void
* @date: 2023/8/10
**/
@Test
void isOverlapLocalTime() {
LocalTime start1 = LocalTime.now();
LocalTime end1 = start1.plusHours(2);
LocalTime start2 = start1.plusHours(2);
LocalTime end2 = start1.plusHours(5);
log.info("start1:{},end1:{},start2:{},end2:{}", start1, end1, start2, end2);
log.info("isOverlap:{}", DateUtils.isOverlapLocalTime(start1, end1, start2, end2, true));
}
返回结果:true
3、数据库实现
同表sql使用公共方式
SELECT *
FROM table_name t1, table_name t2
WHERE t1.id <> t2.id
AND t1.start_time <= t2.end_time AND t1.end_time >= t2.start_time;
t1.id <> t2.id 用于排除同一行数据的比较。这个语句会将表中的每一行数据与其他行数据进行比较,如果存在重叠的时间段,则返回结果集。
建表
CREATE TABLE `test_date` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`start_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_start_time`(`start_time` ASC) USING BTREE,
INDEX `idx_end_time`(`end_time` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
添加数据
INSERT INTO `test_date` VALUES (1, '2021-08-05 11:19:01', '2021-08-31 11:19:01');
INSERT INTO `test_date` VALUES (2, '2010-08-27 18:56:13', '2010-09-05 18:56:13');
INSERT INTO `test_date` VALUES (3, '2015-08-08 07:31:37', '2015-09-30 07:31:37');
INSERT INTO `test_date` VALUES (4, '2012-07-16 07:11:41', '2012-07-31 07:11:41');
INSERT INTO `test_date` VALUES (5, '2001-08-21 09:23:11', '2006-11-05 05:28:14');
INSERT INTO `test_date` VALUES (6, '2001-06-07 10:50:32', '2007-12-22 12:45:20');
INSERT INTO `test_date` VALUES (7, '2019-03-29 20:55:14', '2019-04-30 20:55:14');
INSERT INTO `test_date` VALUES (8, '2010-10-21 10:10:27', '2014-07-10 13:18:35');
INSERT INTO `test_date` VALUES (9, '2008-08-12 03:39:36', '2015-09-05 20:17:57');
INSERT INTO `test_date` VALUES (10, '2020-03-24 00:39:22', '2023-10-21 17:26:11');
测试
sql语句:id!=10为排除同一行数据
SELECT
*
FROM
test_date
WHERE
id != 10
AND start_time <= "2023-10-21 17:26:11" AND end_time >= '2020-03-24 00:39:22';
结果如下,存在1条重叠数据