判断时间段是否重叠

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条重叠数据

判断时间段是否重叠_第1张图片

 

你可能感兴趣的:(数据库,java,工具,oracle,数据库)