java如何判断时间段是否交叉重叠

 更新时间:2023年12月21日 15:41:31   作者:王素健  
这篇文章主要介绍了java如何判断时间段是否交叉重叠问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1.需求

要求保存每一条数据的startTime、endTime的中间时间段是唯一的,跟其他数据时间段不能存在冲突

比如:

(2019-03-01 -> 2019-03-03 ) (2019-03-02 -> 2019-03-04 )

这两个时间段存在重叠部分

2.思路

首先,校验前端传的list自身先比较是否有时间冲突;

然后,校验前端List跟数据库存在的list是否有时间冲突;

方法:两次for循环list实现

3.代码部分

*实体类*

/**
 * @Param:
 * @Description: 实体类
 * @Author: zyf    2019/3/29
 */
class TimeModel {
    private Long jobId; //主键
    private Date startTime;//开始时间
    private Date endTime;   //结束时间
    //getter/setter
}

*前端显示日期格式*

public static final String DATE_FORMAT_Y_M_DHM = "yyyy-MM-dd HH:mm"; //比较日期计算到分钟,当然数据库里面存的数据一般精确到秒
// date转String
    public static String dateToStr(Date date) {
        String strDate = "";
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_Y_M_DHM);
        strDate = sdf.format(date);
        return strDate;
    }

前端List数据校验(自身)

 /**
     * @Param:
     * @Description: list自身查询有无时间冲突,
     * 优化1: 如果自身的list过大, j遍历不能从0开始,只需要往后面数据比较大小
     * @Author: zyf    2019/3/29
     */
    public static String checkSelf(List<TimeModel> list) {
        String res = null;
        if (list.size() == 0) {
            return res;
        }
        for (int i = 0; i < list.size(); i++) {
            // long I_S = list.get(i).getEffectiveStartTime().getTime();
            // long I_E = list.get(i).getEffectiveEndTime().getTime();
            Date I_S = list.get(i).getStartTime();
            Date I_E = list.get(i).getEndTime();
           // for (int j = 0; j < list.size(); j++) {
            for (int j = i+1; j < list.size(); j++) {
               /* if (i == j) {
                    continue;  //自身不跟自身比较
                }*/
                Date J_S = list.get(j).getStartTime();
                Date J_E = list.get(j).getEndTime();
                //这里使用compareTo方法, 因为getTime()的时间不太准确
                if ((J_S.compareTo(I_S) == -1 && I_S.compareTo(J_E) == -1)
                        || (J_S.compareTo(I_E) == -1 && I_E.compareTo(J_E) == -1)
                || (I_S.compareTo(J_S) == -1 && J_S.compareTo(I_E) == -1)   //新加部分
                || (I_S.compareTo(J_E) == -1 && J_E.compareTo(I_E) == -1)   //新加部分

|| J_E.compareTo(I_S) == 0 || J_S.compareTo(I_E) == 0
                        || J_E.compareTo(I_E) == 0 || J_S.compareTo(I_S) == 0) {
                    res =  dateToStr(list.get(i).getStartTime()) + " "
                            + dateToStr(list.get(i).getEndTime());
                    break;
                }
            }
        }
        return res;
    }

前端list和数据库存在数据list比较

/**
     * @Param: listNew 前端传的list
     * @Param: listOld 数据库list,
     * 优化2*****后端查询数据库可以根据前端的list里面最大时间和最小时间区间作为条件查询出来
     * @Description: 比较前端传的list跟数据库list有无时间冲突
     * @Author: zyf    2019/3/29
     */
    public static String checkTwoList(List<TimeModel> listNew, List<TimeModel> listOld) {
        String res = null;  //没有冲突返回null,有冲突返回冲突的时间段
        for (int i = 0; i < listNew.size(); i++) {
            Date I_S = listNew.get(i).getStartTime();
            Date I_E = listNew.get(i).getEndTime();
            Long jobIdNew = listNew.get(i).getJobId();
            for (int j = 0; j < listOld.size(); j++) {
                Long jobIdOld = listOld.get(j).getJobId();
                Date J_S = listOld.get(j).getStartTime();
                Date J_E = listOld.get(j).getEndTime();

                if (jobIdNew != null && jobIdNew.longValue() == jobIdOld.longValue()) {
                    continue; // 前台如果是旧数据修改不能再跟自己比较
                }
                //compareTo返回结果-1 0 1 表示前者比后者<,=,>关系 ,下面的if判断涉及具体的怎样比较可以自行优化
                if ((J_S.compareTo(I_S) == -1 && I_S.compareTo(J_E) == -1)
                        || (J_S.compareTo(I_E) == -1 && I_E.compareTo(J_E) == -1)                        || (I_S.compareTo(J_S) == -1 && J_S.compareTo(I_E) == -1)   //新加部分                || (I_S.compareTo(J_E) == -1 && J_E.compareTo(I_E) == -1)   //新加部分
                        || J_E.compareTo(I_S) == 0 || J_S.compareTo(I_E) == 0
                        || J_E.compareTo(I_E) == 0 || J_S.compareTo(I_S) == 0) {
                    res = dateToStr(listNew.get(i).getStartTime()) + " "
                            + dateToStr(listNew.get(i).getEndTime());
                    break;
                }
            }
        }
        return res;
    }

测试

//测试
    @Test
    public void test01() {

        /*
        * 这里模拟一下数据库存储的时间格式,精确到秒,实际情况直接进行比较的是Date类型
        * 注意:时间点不能相等
        * */
        //model1 的开始-结束时间  2019-03-01 14:51:00  2019-03-05 14:52:00
        //model2 的开始-结束时间  2019-03-05 14:53:00  2019-03-05 14:54:00
        //model3 的开始-结束时间  2019-03-02 14:53:00  2019-03-05 14:53:00

        List<TimeModel> list = new ArrayList<>();
        List<TimeModel> listOld = new ArrayList<>();
        TimeModel mode1 = new TimeModel();
        mode1.setStartTime(strToDate("2019-03-01 14:51:00"));
        mode1.setEndTime(strToDate("2019-03-05 14:52:00"));

        TimeModel mode2 = new TimeModel();
        //mode2.setStartTime(strToDate("2019-03-05 14:51:00"));  //checkSelf()使用
        mode2.setStartTime(strToDate("2019-03-05 14:53:00")); //checkTwoList()使用
        mode2.setEndTime(strToDate("2019-03-05 14:54:00"));

        TimeModel mode3 = new TimeModel();
        mode3.setStartTime(strToDate("2019-03-02 14:53:00"));
        mode3.setEndTime(strToDate("2019-03-05 14:58:00"));

        list.add(mode1);
        list.add(mode2);

        //String res = checkSelf(list);  //checkSelf()使用

        listOld.add(mode3);  //checkTwoList()使用
        String res = checkTwoList(list,listOld);
        System.out.println("冲突的时间段:"  + res);

    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 如何在Java SpringBoot项目中配置动态数据源你知道吗

    如何在Java SpringBoot项目中配置动态数据源你知道吗

    这篇文章主要介绍了SpringBoot如何在运行时动态添加数据源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-09-09
  • mybatis查询SqlServer慢问题及解决

    mybatis查询SqlServer慢问题及解决

    这篇文章主要介绍了mybatis查询SqlServer慢问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Java线性表的顺序表示及实现

    Java线性表的顺序表示及实现

    这篇文章主要介绍了Java线性表的顺序表示及实现,顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中
    2022-07-07
  • Spring Boot 项目在 K8S 中的打包、部署与运维发布实践指南

    Spring Boot 项目在 K8S 中的打包、部署与运维发布实践指南

    文章介绍了运维工程师掌握SpringBoot+Docker+K8S+JVM的基础知识和发布流程,包括Java项目的交付物、SpringBoot构建流程、Jenkins流水线发布、JVM配置和优化等,帮助运维理解从源码到上线的完整交付视角,提升发布成功率和故障排查能力,感兴趣的朋友一起看看吧
    2026-05-05
  • SpringSecurity显示用户账号已被锁定的原因及解决方案

    SpringSecurity显示用户账号已被锁定的原因及解决方案

    SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNonLocked()等方法的逻辑,确保返回正确状态,避免误判账户锁定,从而允许合法用户登录,下面给大家介绍SpringSecurity显示用户账号已被锁定的解决方案,感兴趣的朋友一起看看吧
    2025-06-06
  • Java中自动装箱、拆箱引起的耗时详解

    Java中自动装箱、拆箱引起的耗时详解

    这篇文章主要给大家介绍了关于Java中自动装箱、拆箱引起的耗时的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • 通过JDK源码角度分析Long类详解

    通过JDK源码角度分析Long类详解

    这篇文章主要给大家介绍了关于通过JDK源码角度分析Long类的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用long类具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • Java代码实现从HTML文件中提取纯文本内容

    Java代码实现从HTML文件中提取纯文本内容

    在 Java 数据处理、文本清洗、内容解析等开发场景中,从 HTML 文件中剔除标签、样式、脚本等冗余格式,提取核心纯文本是高频需求,下面我们就来看看如何使用Java实现从HTML文件中提取纯文本内容吧
    2026-04-04
  • SpringBoot项目启动错误:找不到或无法加载主类的三种解决方法

    SpringBoot项目启动错误:找不到或无法加载主类的三种解决方法

    在开发SpringBoot应用时,经常可能会遇到一个启动错误:“错误:找不到或无法加载主类 com.example.controller.demo.DemoApplication”,本文将介绍三种解决这一问题的方法,需要的朋友可以参考下
    2024-10-10
  • java编程枚举类型那些事!枚举类型定义和重写枚举的方法

    java编程枚举类型那些事!枚举类型定义和重写枚举的方法

    本文主要介绍了枚举类型的有关内容,涉及简单的枚举类型定义,以及枚举类型的值在Java中的定义方法,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10

最新评论