计算两段时间之间的工作日的天/小时/分钟/秒数

我们能经常遇到一些需求,让获取工作日的时间(当然,调休也上班也是工作日哈!),之前自己给这搞得头大,所以整理总结,把该工具类记录下来,希望大家能用到的时候可以直接使用!

在该工具类中主要用到了 java.util 包下的Calendar 这个日期类

大致实现原理:

  • 首先我们需要使用两个List将一年的工作日和非工作日的日期存起来,以便后面的判断。

    • (SPECIAL_WORK_DAYS)特别的工作日(周六,周日上班的日期集合)
    • (SPECIAL_OFF_DAYS)特别的休息日(周一到周五休息的日期集合)
  • 其次,定义一个变量,代表工作日的天数(若日期是yy-MM-dd格式的,Integer类型就可以,如果是yy-MM-dd HH:mm:ss格式的,想更精确的,则定义成Double类型即可)。
    • workDaysNum (工作日天或小时)
  • 其次,获取两个时间段,进行循环比较,判断距现在较远的日期是否是非工作日。(开始时间–startTime,结束时间–endTime)
动手搞起来

新建CalcWorkDaysUtil.java类

方案一:

计算 时间格式为(yy-MM-dd) 的两时间段工作日天数的 完整代码:

/*** @Title: 计算时间周期之间工作日的时间* @Author: Sophia* #Description: CalcWorkDaysUtil* #Date: 2022/6/2 14:42*/
public class CalcWorkDaysUtil {// 定义2个List用于存储特殊的工作日和非工作日// 特别的工作日(周六,周日上班的日期集合)private static List<String> SPECIAL_WORK_DAYS = new ArrayList<>();// 特别的休息日(周一到周五休息的日期集合)private static List<String> SPECIAL_OFF_DAYS = new ArrayList<>();// 在这里我就使用静态将2022年所有的节假日存到相应的list中// 大多是都是从数据库中获取的(这里就这样演示,大家后期可以从数据库获取)static {// 特殊的工作日(周六,周日上班的日期集合)SPECIAL_WORK_DAYS.add("2022-01-29");SPECIAL_WORK_DAYS.add("2022-01-30");SPECIAL_WORK_DAYS.add("2022-04-02");SPECIAL_WORK_DAYS.add("2022-04-24");SPECIAL_WORK_DAYS.add("2022-05-07");SPECIAL_WORK_DAYS.add("2022-10-08");SPECIAL_WORK_DAYS.add("2022-10-09");// 特殊的休息日(周一到周五休息的日期集合)SPECIAL_OFF_DAYS.add("2022-01-01");SPECIAL_OFF_DAYS.add("2022-01-02");SPECIAL_OFF_DAYS.add("2022-01-03");SPECIAL_OFF_DAYS.add("2022-01-31");SPECIAL_OFF_DAYS.add("2022-02-01");SPECIAL_OFF_DAYS.add("2022-02-02");SPECIAL_OFF_DAYS.add("2022-02-03");SPECIAL_OFF_DAYS.add("2022-02-04");SPECIAL_OFF_DAYS.add("2022-02-05");SPECIAL_OFF_DAYS.add("2022-02-06");SPECIAL_OFF_DAYS.add("2022-04-03");SPECIAL_OFF_DAYS.add("2022-04-04");SPECIAL_OFF_DAYS.add("2022-04-05");SPECIAL_OFF_DAYS.add("2022-04-30");SPECIAL_OFF_DAYS.add("2022-05-01");SPECIAL_OFF_DAYS.add("2022-05-02");SPECIAL_OFF_DAYS.add("2022-05-03");SPECIAL_OFF_DAYS.add("2022-05-04");SPECIAL_OFF_DAYS.add("2022-06-03");SPECIAL_OFF_DAYS.add("2022-06-04");SPECIAL_OFF_DAYS.add("2022-06-05");SPECIAL_OFF_DAYS.add("2022-09-10");SPECIAL_OFF_DAYS.add("2022-09-11");SPECIAL_OFF_DAYS.add("2022-09-12");SPECIAL_OFF_DAYS.add("2022-10-01");SPECIAL_OFF_DAYS.add("2022-10-01");SPECIAL_OFF_DAYS.add("2022-10-02");SPECIAL_OFF_DAYS.add("2022-10-03");SPECIAL_OFF_DAYS.add("2022-10-04");SPECIAL_OFF_DAYS.add("2022-10-05");SPECIAL_OFF_DAYS.add("2022-10-06");SPECIAL_OFF_DAYS.add("2022-10-07");}// 日期格式化方法(非线程安全的,可根据情况在方法内使用,或使用DateTimeFormatter)private static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");/*** 计算两时间段的工作日的天数* @param startTimeStr 开始时间* @param endTimeStr 结束时间* @return*/private static Integer getWorkDaysNum(String startTimeStr, String endTimeStr) {// 准备工作// 定义Integer类型的工作日天数标识 (注:如果精确小时、分、秒,可用double)Integer workDaysNum = 0; // 默认0天// 获取两个日期对象Calendar cale1 = Calendar.getInstance();Calendar cale2 = Calendar.getInstance();// 将开始时间和结束时间转换成Date类型并设置到日历中try {// 格式转换Date startDate = SDF.parse(startTimeStr);Date endDate = SDF.parse(endTimeStr);// 设置到日历cale1.setTime(startDate);cale2.setTime(endDate);} catch (ParseException e) {System.out.println("日期转换异常,请检查日期格式!");e.printStackTrace();}// 准备工作已准备完毕// 当开始时间小于等于结束时间时,进行循环判断while (cale1.compareTo(cale2) <= 0) {// 如果cale1不是周六日, workDaysNum则加一天// 周日 --> 1,周一 --> 2,周二 --> 3,周三 --> 4,周四 --> 5,周五 --> 6,周六 --> 7if (cale1.get(Calendar.DAY_OF_WEEK) != 7 && cale1.get(Calendar.DAY_OF_WEEK) != 1) {// 不是周六日,workDaysNum + 1workDaysNum++;// 判断是不是特殊的休息日(周一到周五休息的日期)//如果不是周六日,判断该日是否属于国家法定节假日或特殊放假日,是 workDaysNum - 1if (SPECIAL_OFF_DAYS.contains(SDF.format(cale1.getTime()))) {// 是,则 - 1workDaysNum--;}}// 如果改日是周六日,则判断改日是否是特别的工作日(周六,周日上班的日期)if (SPECIAL_WORK_DAYS.contains(SDF.format(cale1.getTime()))) {// 如果是改日是特殊的工作日,则 + 1workDaysNum++;}// 将时间向后设置一天继续判断cale1.add(Calendar.DAY_OF_MONTH, 1);}// 循环结束,将这两时间段的工作日返回出去return workDaysNum;}public static void main(String[] args) {String startTimeStr = "2022-05-20";String endTimeStr = "2022-06-09";Integer workDaysNum = getWorkDaysNum(startTimeStr, endTimeStr);System.out.println(startTimeStr + " 到 " + endTimeStr + " 之间的工作日为:" + workDaysNum + "天");}
}
方案二:

计算 时间格式为(yy-MM-dd HH:mm:ss) 的两时间段工作日的天/小时/分钟/秒数的 完整代码:

package fit.clover.blog.util;import org.apache.commons.lang3.StringUtils;import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;/*** @Title: 计算时间周期之间工作日的时间* @Author: Sophia* #Description: CalcWorkDaysUtil* #Date: 2022/6/2 14:42*/
public class CalcWorkDaysUtil {// 定义2个List用于存储特殊的工作日和非工作日// 特别的工作日(周六,周日上班的日期集合)private static List<String> SPECIAL_WORK_DAYS = new ArrayList<>();// 特别的休息日(周一到周五休息的日期集合)private static List<String> SPECIAL_OFF_DAYS = new ArrayList<>();// 在这里我就使用静态将2022年所有的节假日存到相应的list中// 大多是都是从数据库中获取的(这里就这样演示,大家后期可以从数据库获取)static {// 特殊的工作日(周六,周日上班的日期集合)SPECIAL_WORK_DAYS.add("2022-01-29");SPECIAL_WORK_DAYS.add("2022-01-30");SPECIAL_WORK_DAYS.add("2022-04-02");SPECIAL_WORK_DAYS.add("2022-04-24");SPECIAL_WORK_DAYS.add("2022-05-07");SPECIAL_WORK_DAYS.add("2022-10-08");SPECIAL_WORK_DAYS.add("2022-10-09");// 特殊的休息日(周一到周五休息的日期集合)SPECIAL_OFF_DAYS.add("2022-01-01");SPECIAL_OFF_DAYS.add("2022-01-02");SPECIAL_OFF_DAYS.add("2022-01-03");SPECIAL_OFF_DAYS.add("2022-01-31");SPECIAL_OFF_DAYS.add("2022-02-01");SPECIAL_OFF_DAYS.add("2022-02-02");SPECIAL_OFF_DAYS.add("2022-02-03");SPECIAL_OFF_DAYS.add("2022-02-04");SPECIAL_OFF_DAYS.add("2022-02-05");SPECIAL_OFF_DAYS.add("2022-02-06");SPECIAL_OFF_DAYS.add("2022-04-03");SPECIAL_OFF_DAYS.add("2022-04-04");SPECIAL_OFF_DAYS.add("2022-04-05");SPECIAL_OFF_DAYS.add("2022-04-30");SPECIAL_OFF_DAYS.add("2022-05-01");SPECIAL_OFF_DAYS.add("2022-05-02");SPECIAL_OFF_DAYS.add("2022-05-03");SPECIAL_OFF_DAYS.add("2022-05-04");SPECIAL_OFF_DAYS.add("2022-06-03");SPECIAL_OFF_DAYS.add("2022-06-04");SPECIAL_OFF_DAYS.add("2022-06-05");SPECIAL_OFF_DAYS.add("2022-09-10");SPECIAL_OFF_DAYS.add("2022-09-11");SPECIAL_OFF_DAYS.add("2022-09-12");SPECIAL_OFF_DAYS.add("2022-10-01");SPECIAL_OFF_DAYS.add("2022-10-01");SPECIAL_OFF_DAYS.add("2022-10-02");SPECIAL_OFF_DAYS.add("2022-10-03");SPECIAL_OFF_DAYS.add("2022-10-04");SPECIAL_OFF_DAYS.add("2022-10-05");SPECIAL_OFF_DAYS.add("2022-10-06");SPECIAL_OFF_DAYS.add("2022-10-07");}// 日期格式化方法(非线程安全的,可根据情况在方法内使用,或使用DateTimeFormatter)private static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");private static SimpleDateFormat SDFS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** 计算两时间段的工作日的天/小时/分钟/秒数* @param startTimeStr 开始时间* @param endTimeStr 结束时间* @param flag d为天,h为小时,m为分钟,s为秒* @return*/private static Double getWorkDaysNum(String startTimeStr, String endTimeStr, String flag) {// 准备工作// 定义Long类型的工作日天数标识 (注:如果精确小时、分、秒,可用double)Long workDaysNum = 0l; // 默认0秒// 定义Double类型的工作日秒数标识Double workDaysSecond = 0d; // 默认0秒// 获取两个日期对象Calendar cale1 = Calendar.getInstance();Calendar cale2 = Calendar.getInstance();// 将开始时间和结束时间转换成Date类型并设置到日历中try {// 设置到日历cale1.setTime(SDF.parse(startTimeStr));cale2.setTime(SDF.parse(endTimeStr));// 格式转换Date startDate = SDFS.parse(startTimeStr);Date endDate = SDFS.parse(endTimeStr);// 设置时间开始区间的0时,如startDateStr 为2022-05-10 10:00:00, 则距2022-05-10 0:00:00点为10个小时,也是600分钟,也是36000秒startTimeStr = StringUtils.substringBeforeLast(startTimeStr, " ") + " 00:00:00";// 设置时间结束区间的24时,如endTimeStr 为2022-06-06 12:00:00 则距2022-06-06 23:59:59点为12个小时,也是720分钟,也是43200秒endTimeStr = StringUtils.substringBeforeLast(endTimeStr, " ") + " 23:59:59";Date startDateZero = SDFS.parse(startTimeStr);Date endDateZero = SDFS.parse(endTimeStr);// 计算开始区间时间距0时的毫秒值long startLong = (startDate.getTime() - startDateZero.getTime());// 计算结束区间时间距24时的毫秒值long endLong = (endDateZero.getTime() - endDate.getTime());// 准备工作已准备完毕// 当开始时间小于等于结束时间时,进行循环判断while (cale1.compareTo(cale2) <= 0) {// 如果cale1不是周六日, workDaysNum则加一天// 周日 --> 1,周一 --> 2,周二 --> 3,周三 --> 4,周四 --> 5,周五 --> 6,周六 --> 7if (cale1.get(Calendar.DAY_OF_WEEK) != 7 && cale1.get(Calendar.DAY_OF_WEEK) != 1) {// 不是周六日,workDaysNum + 1workDaysNum++;// 判断是不是特殊的休息日(周一到周五休息的日期)//如果不是周六日,判断该日是否属于国家法定节假日或特殊放假日,是 workDaysNum - 1if (SPECIAL_OFF_DAYS.contains(SDF.format(cale1.getTime()))) {// 是,则 - 1workDaysNum--;}}// 如果改日是周六日,则判断改日是否是特别的工作日(周六,周日上班的日期)if (SPECIAL_WORK_DAYS.contains(SDF.format(cale1.getTime()))) {// 如果是改日是特殊的工作日,则 + 1workDaysNum++;}// 将时间向后设置一天继续判断cale1.add(Calendar.DAY_OF_MONTH, 1);}// 将天转成毫秒值workDaysNum = workDaysNum * 86400000; // 一天等于86400000毫秒// 天数计算完毕,使用BigDecimal将天数换成秒BigDecimal daysNumDec = new BigDecimal(workDaysNum);// 将天转换成秒BigDecimal tempNum = daysNumDec;// .multiply(secondDec);tempNum = tempNum.subtract(new BigDecimal(startLong));tempNum = tempNum.subtract(new BigDecimal(endLong));if ("d".equals(flag)) {// 天workDaysSecond = tempNum.divide(new BigDecimal("86400000"), 2, RoundingMode.HALF_UP).doubleValue(); // 24*60*60秒 = 1天} else if ("h".equals(flag)) {// 小时workDaysSecond = tempNum.divide(new BigDecimal("3600000"), 2, RoundingMode.HALF_UP).doubleValue(); // 60*60秒 = 1小时} else if ("m".equals(flag)) {// 分钟workDaysSecond = tempNum.divide(new BigDecimal("60000"), 2, RoundingMode.HALF_UP).doubleValue(); // 60秒 = 1分钟} else if ("s".equals(flag)) {// 秒workDaysSecond = tempNum.divide(new BigDecimal("1000"), 2, RoundingMode.HALF_UP).doubleValue();}} catch (ParseException e) {System.out.println("日期转换异常,请检查日期格式!");e.printStackTrace();}// 循环结束,将这两时间段的工作日返回出去return workDaysSecond;}public static void main(String[] args) {String startTimeStr = "2022-06-01 03:00:00";String endTimeStr = "2022-06-06 12:00:00";Double days = getWorkDaysNum(startTimeStr, endTimeStr, "d");Double hour = getWorkDaysNum(startTimeStr, endTimeStr, "h");Double min = getWorkDaysNum(startTimeStr, endTimeStr, "m");Double second = getWorkDaysNum(startTimeStr, endTimeStr, "s");System.out.println(startTimeStr + " 到 " + endTimeStr + " 之间的工作日为:" + days + "天");System.out.println(startTimeStr + " 到 " + endTimeStr + " 之间的工作日为:" + hour + "小时");System.out.println(startTimeStr + " 到 " + endTimeStr + " 之间的工作日为:" + min + "分钟");System.out.println(startTimeStr + " 到 " + endTimeStr + " 之间的工作日为:" + second + "秒");}
}

运行结果:

总结:当然还是推荐使用方案二的,因为方案二可根据不同的标识获取不同的单位数的!

使用Java的Calendar类计算两段时间之间的工作日的天/小时/分钟/秒数相关推荐

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

    说明: 有时候我们在计算时间时,有让获取两时间段重合的天数这种需求,小编也是遇到了这样的需求,就封装了一个工具类,希望能帮助到大家. 我们先进行分析 求两个时间段重合的天数,例如求(2022-05-0 ...

  2. java 计算两个时间之间的间隔

    1. 怎样计算两个时间之间的间隔? 间隔=Date1.getTime()-Date2.getTime();得出来的是毫秒数. 除1000是秒,再除60是分,再除60是小时............... ...

  3. Java计算两个时间点的工作日

    在做项目时遇到一个需求,需要计算两个时间点之间的工作日.便于统计项目时间统计. 其中有两个方向: 第一,调用开源的api,"http://api.goseek.cn/Tools/holida ...

  4. Calendar计算两个时间之间相差几个月

    目录 说明 说明 计算两个时间之间相差几个月: public int getMonth(String startDt, String endDt) {int month = 0;try {Simple ...

  5. 怎样计算两个时间之间的间隔

    怎样计算两个时间之间的间隔 1. 怎样计算两个时间之间的间隔? 间隔=Date1.getTime()-Date2.getTime();得出来的是毫秒数. 除1000是秒,再除60是分,再除60是小时. ...

  6. oracle 节假日天数,强大的PLSQL - 计算两个日期之间的工作日天数-除去(周末和公共假日...

    用php写了一个函数,实现的功能是 计算两个日期之间的工作日天数-除去(周末和公共假日)写了 300多行的代码,  实现公共假日从文件中读取, 或者从数据库提取, 然后传入两个日期,就能返回想要的结果 ...

  7. 计算两个时间之间的工作时长

    计算两个时间之间的工作时长(小时)排除周末 package com.test;import org.apache.commons.lang3.time.DateUtils;import java.ma ...

  8. 计算两个时间相差的工作日(附带查询api接口)

    /*** 两个日期相减* @param beginDateStr* @param endDateStr* @return*/ public static long getDaySub(String b ...

  9. python时间差转换成天数_Python实现计算两个时间之间相差天数的方法

    本文实例讲述了Python实现计算两个时间之间相差天数的方法.分享给大家供大家参考,具体如下: #-*- encoding:UTF-8 -*- from datetime import date im ...

最新文章

  1. 为图片添加半透明遮罩效果
  2. PHP函数,方法,接口
  3. 内存heap_哪个内存更快?Heap或ByteBuffer或Direct?
  4. 贾扬清演讲实录:一个AI开发者的奇幻漂流
  5. Android application project 各个文件夹作用
  6. java定时产生随机数_浅析Java随机数与定时器
  7. leetcode933.NumberofRecentCalls
  8. 视频云存储平台 备忘
  9. Tomcat安装及配置教程
  10. pdf 分形 张济忠_分形理论及其研究方法.pdf
  11. 关于lua加密luac的有关问题
  12. QLabel 添加下划线 删除线
  13. 怎么删除服务器的ibd文件,mysql数据库ibd文件
  14. Web登录如何确保安全
  15. php几个时间段去除重复,一个时间段内各地区数据和,发现重复地区不相加
  16. 520,都来被虐吧。。。
  17. 理解计算机(2)—什么是云主机
  18. 美国计算机教育方向相关的论文题目,浅谈美国大学计算机教育论文
  19. 跨境电商必读:什么是社交媒体营销?
  20. 路由器上的usb接口有什么用_解决USB接口不够用,毕亚兹Type-C扩展坞体验测评

热门文章

  1. 英文论文怎么做实验?
  2. 设计简单通讯录系统 普通数组和vector数组实现
  3. 【光通信】各类线缆的最大传输距离,你都了解吗?
  4. idea 启动shorten command line too long 错误解析
  5. 使用Beaglebone Black的PRU(一)
  6. Matlab强化学习——部署策略
  7. 红帽linux配置syslog,linux syslog配置
  8. 简述http和https区别
  9. ca开头的车是什么牌子_ca开头的车是什么牌子
  10. “羊了个羊”Java版本实现