在js中计算两个时间段重叠的时长问题


前言

最近遇到一个需求,就是在js中计算两段时间的重叠时长问题,这里记录一下。


一、过程分析

两段时间的重叠问题,一般有3中情况

  1. 两段时间完全无重叠,也就是无任何交集
  2. 两段时间有交叉
  3. 两段时间有包含关系

为了弄清楚这个关系,我画了一张图来说明:

在这里插入图片描述

根据这张图上的内容,我们可以按照步骤来逐个实现。

  1. 第一种情况,明显没有重叠,所以为0
  2. 第二种情况,交叉情况下可能的结果是:end1-start2或者end2-start1
  3. 第三种情况,包含关系下可能的结果是:end2-start2或者end1-start1

根据上面的分析,我们可以直接写代码

二、实现代码(js)

JavaScript处理日期我推荐一个插件库【Moment.js】点击官网
使用这个工具我们就能很轻松处理日期的各种操作。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
</head>
<body>
<script>
    //两个时间段重复的时段,返回秒数
    //传入两个数组
    function bw(times1,times2){
        if(!Array.isArray(times1) || !Array.isArray(times2) || times1.length!=2 || times2.length!=2){
            console.log('参数错误1')
            return 0;
        }
        var start1=moment(times1[0]);
        var end1=moment(times1[1]);
        var start2=moment(times2[0]);
        var end2=moment(times2[1]);

        if(!start1.isValid() || !end1.isValid() || !start2.isValid() || !end2.isValid()){
            console.log('参数错误2')
            return 0;
        }

        //先判断数据正确性
        if(start1.isAfter(end1) || start2.isAfter(end2)){
            console.log('时间范围不正确')
            return 0;
        }
        //第一种情况
        if(end1.isSameOrBefore(start2) || end2.isSameOrBefore(start1)) {
            console.log('两段时间无交叉')
            return 0;
        }
        //第二种情况:1,这种情况就是end1-start2
        if(start1.isSameOrBefore(start2) && end1.isSameOrBefore(end2) && start2.isSameOrBefore(end1)){
            var duration = moment.duration(end1.diff(start2))
            //duration.as('hours');
            //duration.as('minutes');
            //duration.as('seconds');
            //duration.as('milliseconds');
            console.log('交叉情况1')
            return duration.as('seconds')
        }
        //第二种情况:2,这种情况就是end2-start1
        if(start2.isSameOrBefore(start1) && end2.isSameOrBefore(end1) && start1.isSameOrBefore(end2)){
            var duration = moment.duration(end2.diff(start1))
            //duration.as('hours');
            //duration.as('minutes');
            //duration.as('seconds');
            //duration.as('milliseconds');
            console.log('交叉情况2')
            return duration.as('seconds')
        }
        //第三种情况:1,time1包含time2 这是就是:end2-start2
        if(start1.isSameOrBefore(start2) && end2.isSameOrBefore(end1)){
            var duration = moment.duration(end2.diff(start2))
            //duration.as('hours');
            //duration.as('minutes');
            //duration.as('seconds');
            //duration.as('milliseconds');
            console.log('包含情况1')
            return duration.as('seconds')
        }
         //第三种情况:2,time2包含time1 这是就是:end1-start1
        if(start2.isSameOrBefore(start1) && end1.isSameOrBefore(end2)){
            var duration = moment.duration(end1.diff(start1))
            //duration.as('hours');
            //duration.as('minutes');
            //duration.as('seconds');
            //duration.as('milliseconds');
            console.log('包含情况2')
            return duration.as('seconds')
        }
        console.log('未匹配到任何模式')
        return 0
    }
    //测试
    //1、数据正确性
    console.log(bw(['2024-01-01 00:03:01','2024-01-01 00:01:01'],['2024-01-01 00:00:50','2024-01-01 00:01:55']))
    //2、两段时间无交叉
    console.log(bw(['2024-01-01 00:01:01','2024-01-01 00:01:01'],['2024-01-02 00:00:50','2024-01-02 00:01:55']))
    //3、交叉情况1
    console.log(bw(['2024-01-01 00:00:01','2024-01-01 00:01:01'],['2024-01-01 00:00:50','2024-01-01 00:01:55']))
    //4、交叉情况2
    console.log(bw(['2024-01-01 00:00:50','2024-01-01 00:01:55'],['2024-01-01 00:00:01','2024-01-01 00:01:01']))
    //5、包含情况1
    console.log(bw(['2024-01-01 00:00:01','2024-01-01 00:01:55'],['2024-01-01 00:00:50','2024-01-01 00:01:01']))
    //6、包含情况2
    console.log(bw(['2024-01-01 00:00:50','2024-01-01 00:01:01'],['2024-01-01 00:00:01','2024-01-01 00:01:55']))

</script>
</body>
</html>

上面代码测试结果为:
在这里插入图片描述


总结

上面的代码略显啰嗦,大家有更好的方法欢迎留言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流年五十前

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值