说明:

有时候我们在计算时间时,有让获取两时间段重合的天数这种需求,小编也是遇到了这样的需求,就封装了一个工具类,希望能帮助到大家。

我们先进行分析

求两个时间段重合的天数,例如求(2022-05-02 00:00:00 至 2022-05-12 23:59:59) 时间段和(2022-05-04 00:00:00 至 2022-05-13 05:00:00)时间段重合(交叉)的天数。

通过我们脑力计算,可获得重合的时间段为 (2022-05-04 00:00:00 至 2022-05-12 23:59:59),也就相当于重合天数为9天。可是这只是一种情况,接下来。我们会对重合(交叉)的情况进行分析:

两个时间段分别是:(aStart -- aEnd), [bStart -- bEnd]
若不好理解,可认为[bStart -- bEnd]是固定时间段,则是计算[aStart -- aEnd]时间段与[bStart -- bEnd]交叉的天数
两个时间段之间的重合天数,有以下几种情况:
情况一:[bStart -- bEnd]在(aStart -- aEnd)时间段内 if(aStart <= bStart && bEnd <= aEnd)(aStart -- [bStart -- bEnd] -- aEnd)
情况二:(aStart -- aEnd)在[bStart -- bEnd]时间段内 if(bStart <= aStart && aEnd <= bEnd)[bStart -- (aStart -- aEnd) -- bEnd]
情况三:(aStart -- aEnd)部分时间在[bStart -- bEnd]时间段内 if(aStart <= bStart && aEnd <= bEnd)(aStart -- [bStart -- aEnd) -- bEnd]
情况四:(aStart -- aEnd)部分时间在[bStart -- bEnd]时间段内 if(bStart <= aStart && bEnd <= aEnd)[bStart -- (aStart -- bEnd] -- aEnd)

经分析,两时间段能重合(交叉)的情况只有这四种情况,其他不能重合(交叉)的情况我们都默认重合天数为0即可。

经分析,我们可以根据这四种情况进行着手计算!

开码

首先,我们需要定义一个方法将String类型的时间格式化成Date并返回转换成Date的时间戳(也就是毫秒值

/*** 时间格式化* @param dateStr String类型时间格式* @return 该时间的时间戳*/public static Long formatDateStr(String dateStr) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = null;try {date = sdf.parse(dateStr);} catch (ParseException e) {e.printStackTrace();System.out.println("时间格式化错误");}return date.getTime();}

之后,定义一个方法,根据标识(flag)计算两个long类型的时间戳之间的天/小时/分钟/秒数

其中flag标识为时间单位标识“d为天,h为小时,m为分钟,s为秒”

/*** 计算两时间之间的时间 天/小时/分钟/秒数* @param bStartLong 开始时间时间戳* @param bEndLong 结束时间时间戳* @param flag 单位标识 d为天,h为小时,m为分钟,s为秒* @return 两时间之间的时间 天/小时/分钟/秒数*/private static Double calcTime(Long bStartLong, Long bEndLong, String flag) {Double result = 0d;Long num = (bEndLong - bStartLong); // 毫秒BigDecimal tempNum = new BigDecimal(num);if ("d".equals(flag)) {// 天result = tempNum.divide(new BigDecimal("86400000"), 2, RoundingMode.HALF_UP).doubleValue(); // 24*60*60秒 = 1天} else if ("h".equals(flag)) {// 小时result = tempNum.divide(new BigDecimal("3600000"), 2, RoundingMode.HALF_UP).doubleValue(); // 60*60秒 = 1小时} else if ("m".equals(flag)) {// 分钟result = tempNum.divide(new BigDecimal("60000"), 2, RoundingMode.HALF_UP).doubleValue(); // 60秒 = 1分钟} else if ("s".equals(flag)) {// 秒result = tempNum.divide(new BigDecimal("1000"), 2, RoundingMode.HALF_UP).doubleValue();}return result;}

最后,对开头分析的四种情况进行判断即可。

/*** 获取两时间段的重合时间* @param aStartStr 时间段1开始时间* @param aEndStr 时间段1结束时间* @param bStartStr 时间段2开始时间* @param bEndStr 时间段2结束时间* @param flag 单位标识 d为天,h为小时,m为分钟,s为秒* @return 重合时间 天/小时/分钟/秒数*/public static Double getIntersectDays(String aStartStr, String aEndStr, String bStartStr, String bEndStr, String flag) {// 时间段1Long aStartLong = formatDateStr(aStartStr);Long aEndLong = formatDateStr(aEndStr);// 时间段2Long bStartLong = formatDateStr(bStartStr);Long bEndLong = formatDateStr(bEndStr);Double num = 0d; // 默认重合(相交)为0// 当符合常规条件时,才进行判断计算if ((aStartLong < aEndLong) && (bStartLong < bEndLong)) {// 四种情况判断if ((aStartLong <= bStartLong) && (bEndLong <= aEndLong)) {// 情况一:只需要计算[bStart -- bEnd]之间的时间即可num = calcTime(bStartLong, bEndLong, flag);} else if ((bStartLong <= aStartLong) && (aEndLong <= bEndLong)) {// 情况二:只需要计算(aStart -- aEnd)之间的时间即可num = calcTime(aStartLong, aEndLong, flag);} else if ((aStartLong <= bStartLong) && (aEndLong <= bEndLong)) {// 情况三:只需要计算(bStart -- aEnd)之间的时间即可num = calcTime(bStartLong, aEndLong, flag);} else if ((bStartLong <= aStartLong) && (bEndLong <= aEndLong)) {// 情况四:只需要计算(bStart -- aEnd)之间的时间即可num = calcTime(aStartLong, bEndLong, flag);} else {// 其他情况,不相交,或者时间组合不符合 默认0}}return num;}
最后进行测试:
 public static void main(String[] args) {String aStartStr = "2022-05-02 00:00:00";String aEndStr = "2022-05-12 23:59:59";String bStartStr = "2022-05-04 00:00:00";String bEndStr = "2022-05-13 05:00:00";Double days = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "d");Double hour = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "h");Double min = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "m");Double second = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "s");System.out.println(days + " 天");System.out.println(hour + " 小时");System.out.println(min + " 分钟");System.out.println(second + " 秒");}

测试结果:

总结:

如果想要计算两时间段的重合的工作日时间,可参考小编的另一篇博文(使用Java的Calendar类计算两段时间之间的工作日的天/小时/分钟/秒数)进行结合封装接口。

完整代码:
package fit.clover.blog.util;import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @Title: 计算两时间段的重合天数* @Author: Sophia* #Description: DateUtil* #Date: 2022/6/7 09:34*/
public class CalcIntersectUtil {/*** 两个时间段分别是:(aStart -- aEnd), [bStart -- bEnd]* 若不好理解,可认为[bStart -- bEnd]是固定时间段,则是计算[aStart -- aEnd]时间段与[bStart -- bEnd]交叉的天数* 两个时间段之间的重合天数,有以下几种情况:*  情况一:[bStart -- bEnd]在(aStart -- aEnd)时间段内 if(aStart <= bStart && bEnd <= aEnd)*      (aStart -- [bStart -- bEnd] -- aEnd)*  情况二:(aStart -- aEnd)在[bStart -- bEnd]时间段内 if(bStart <= aStart && aEnd <= bEnd)*      [bStart -- (aStart -- aEnd) -- bEnd]*  情况三:(aStart -- aEnd)部分时间在[bStart -- bEnd]时间段内 if(aStart <= bStart && aEnd <= bEnd)*      (aStart -- [bStart -- aEnd) -- bEnd]*  情况四:(aStart -- aEnd)部分时间在[bStart -- bEnd]时间段内 if(bStart <= aStart && bEnd <= aEnd)*      [bStart -- (aStart -- bEnd] -- aEnd)*  经过分析,两时间段相交有这4中情况,所以我们可以根据这四种情况进行着手计算*//*** 获取两时间段的重合时间* @param aStartStr 时间段1开始时间* @param aEndStr 时间段1结束时间* @param bStartStr 时间段2开始时间* @param bEndStr 时间段2结束时间* @param flag 单位标识 d为天,h为小时,m为分钟,s为秒* @return 重合时间 天/小时/分钟/秒数*/public static Double getIntersectDays(String aStartStr, String aEndStr, String bStartStr, String bEndStr, String flag) {// 时间段1Long aStartLong = formatDateStr(aStartStr);Long aEndLong = formatDateStr(aEndStr);// 时间段2Long bStartLong = formatDateStr(bStartStr);Long bEndLong = formatDateStr(bEndStr);Double num = 0d; // 默认重合(相交)为0// 当符合常规条件时,才进行判断计算if ((aStartLong < aEndLong) && (bStartLong < bEndLong)) {// 四种情况判断if ((aStartLong <= bStartLong) && (bEndLong <= aEndLong)) {// 情况一:只需要计算[bStart -- bEnd]之间的时间即可num = calcTime(bStartLong, bEndLong, flag);} else if ((bStartLong <= aStartLong) && (aEndLong <= bEndLong)) {// 情况二:只需要计算(aStart -- aEnd)之间的时间即可num = calcTime(aStartLong, aEndLong, flag);} else if ((aStartLong <= bStartLong) && (aEndLong <= bEndLong)) {// 情况三:只需要计算(bStart -- aEnd)之间的时间即可num = calcTime(bStartLong, aEndLong, flag);} else if ((bStartLong <= aStartLong) && (bEndLong <= aEndLong)) {// 情况四:只需要计算(bStart -- aEnd)之间的时间即可num = calcTime(aStartLong, bEndLong, flag);} else {// 其他情况,不相交,或者时间组合不符合 默认0}}return num;}/*** 计算两时间之间的时间 天/小时/分钟/秒数* @param bStartLong 开始时间时间戳* @param bEndLong 结束时间时间戳* @param flag 单位标识 d为天,h为小时,m为分钟,s为秒* @return 两时间之间的时间 天/小时/分钟/秒数*/private static Double calcTime(Long bStartLong, Long bEndLong, String flag) {Double result = 0d;Long num = (bEndLong - bStartLong); // 毫秒BigDecimal tempNum = new BigDecimal(num);if ("d".equals(flag)) {// 天result = tempNum.divide(new BigDecimal("86400000"), 2, RoundingMode.HALF_UP).doubleValue(); // 24*60*60秒 = 1天} else if ("h".equals(flag)) {// 小时result = tempNum.divide(new BigDecimal("3600000"), 2, RoundingMode.HALF_UP).doubleValue(); // 60*60秒 = 1小时} else if ("m".equals(flag)) {// 分钟result = tempNum.divide(new BigDecimal("60000"), 2, RoundingMode.HALF_UP).doubleValue(); // 60秒 = 1分钟} else if ("s".equals(flag)) {// 秒result = tempNum.divide(new BigDecimal("1000"), 2, RoundingMode.HALF_UP).doubleValue();}return result;}/*** 时间格式化* @param dateStr String类型时间格式* @return 该时间的时间戳*/public static Long formatDateStr(String dateStr) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = null;try {date = sdf.parse(dateStr);} catch (ParseException e) {e.printStackTrace();System.out.println("时间格式化错误");}return date.getTime();}public static void main(String[] args) {String aStartStr = "2022-05-02 00:00:00";String aEndStr = "2022-05-12 23:59:59";String bStartStr = "2022-05-04 00:00:00";String bEndStr = "2022-05-13 05:00:00";Double days = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "d");Double hour = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "h");Double min = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "m");Double second = getIntersectDays(aStartStr, aEndStr, bStartStr, bEndStr, "s");System.out.println(days + " 天");System.out.println(hour + " 小时");System.out.println(min + " 分钟");System.out.println(second + " 秒");}
}

希望对你有所帮助!

计算两时间段的重合天/小时/分钟/秒数(末尾附完整代码)相关推荐

  1. 使用Java的Calendar类计算两段时间之间的工作日的天/小时/分钟/秒数

    计算两段时间之间的工作日的天/小时/分钟/秒数 我们能经常遇到一些需求,让获取工作日的时间(当然,调休也上班也是工作日哈!),之前自己给这搞得头大,所以整理总结,把该工具类记录下来,希望大家能用到的时 ...

  2. php 计算日期差几周,PHP计算两个时间之差的函数(年,月,周,日,小时,分钟,秒数)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 PHP 2  // 时间格式为YYYYMMDDHHmmss 3  function timeDiff( $aTime , $bTime ) 4 { 5   ...

  3. JavaScript 实现页面内时间实时倒计时 计时器内附完整文件欢迎调用(可用于抢购倒计时,记录恋爱纪念日总时长等)输出对应的天数小时分钟秒数

    JavaScript 实现页面内时间倒计时 计时器 可用于抢购倒计时,记录恋爱纪念日总时长等输出对应的天数小时分钟秒数 注意:在下一个文章中将公布一个纪念日成品代码,欢迎各位来学习(复制) 第一步:构 ...

  4. java 根据日期计算当前周一和周日,及根据秒数计算天小时分钟秒数等相关日期

    日期工具类 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; ...

  5. Excel计算开始与结束时间之间的小时/分钟/秒数

    可以看到表格中的数据格式是年/月/日 00:00,通过公式计算两格之间的差值: =(F2-E2) 这个是时候计算出来的差值并不是我们需求的分钟和秒数: 对G列单击鼠标右键,点设置单元格格式: 将格式设 ...

  6. JavaScript 实现抢购倒计时,记录恋爱1314纪念日倒计时,输出对应的天数小时分钟秒数

    效果图: 1.先建立两个盒子 <div class="div"><div class="box"> </div></d ...

  7. MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数

    计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数,这里主要分享的是通过MySql内置的函数 TimeStampDiff() 实现. 函数 TimeStampDiff() 是MySQL本身提供的 ...

  8. Python:计算分位数、获取分位数的索引(自定义位置,附完整代码)

    最近写代码需要找数据的百分位数和其索引,但没找到合适的函数,就自己写了一个: 需要说明的是,这里对百分位数的定义为:一组n个观测值按照数值大小排列,处于p%位置的值称第p百分位数.(代码中的gapFr ...

  9. python的datetime举例_Python datetime库计算两个时间点之间的分钟(秒、天)数

    计算两个时间点之间的分钟数 import datetime def minNums(startTime, endTime): '''计算两个时间点之间的分钟数''' # 处理格式,加上秒位 start ...

最新文章

  1. Sobel算子及cvSobel
  2. Android Fragments 详细使用详细介绍
  3. cannot be registered to your development team. Change your bundle identifier to a unique string to t
  4. 腾讯高性能图计算框架Plato及其算法应用
  5. permgen_什么是PermGen泄漏?
  6. 告别传统商务海报版式|绚丽色彩的你,感觉更具现代与活力
  7. ES6学习笔记三(字符串)
  8. SIR模型 matlab模拟
  9. rose 生产java代码m_rose 生成代码
  10. 计算机加域后数据库无法登录,客户端多台计算机登录域失败,显示如下
  11. 修改tomcat 发布war大小限制
  12. Android手机app的adb命令测试电量
  13. Excel如何快速评定考核成绩等级
  14. 【计算机网络】,java基础教程从入门到精通
  15. ECharts地图进去直接显示数字和颜色问题
  16. vue使用参数直接取到data数据
  17. 互联网行业入门必读书籍
  18. 花裤衩 / vue-element-admin 的项目打包后发现不能跳转页面问题解决
  19. 一图带你了解人工智能简史
  20. 淘宝乐视奥比中光深度摄像头不显示RGB图像终极解决办法

热门文章

  1. web 完整轮播图 前端 轮播图 详细
  2. 小红书达人评论区需要维护吗,注意事项
  3. java运行环境的英文缩写_java英文缩写
  4. 104通讯协议01 规约报文结构
  5. Simulink代码生成(二十二)——TSP开发之创建外部设备模块
  6. 反向恢复时间trr的影响
  7. (转)机器学习系列(7)_机器学习路线图(附资料)
  8. 【Transformer】Transformer理论知识
  9. Windows强制删除文件夹
  10. 项目显示红色感叹号问题解决