文章目录
- 前言
- 一、过程分析
- 二、实现代码(js)
- 总结
前言
最近遇到一个需求,就是在js中计算两段时间的重叠时长问题,这里记录一下。
一、过程分析
两段时间的重叠问题,一般有3中情况
- 两段时间完全无重叠,也就是无任何交集
- 两段时间有交叉
- 两段时间有包含关系
为了弄清楚这个关系,我画了一张图来说明:
根据这张图上的内容,我们可以按照步骤来逐个实现。
- 第一种情况,明显没有重叠,所以为0
- 第二种情况,交叉情况下可能的结果是:end1-start2或者end2-start1
- 第三种情况,包含关系下可能的结果是: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>
上面代码测试结果为:
总结
上面的代码略显啰嗦,大家有更好的方法欢迎留言