计算工作日时长
程序员文章站
2022-03-03 10:14:35
...
计算工作日时长
工具类说明:
- mapWorkDay 自定义节假日,主要针对国内每年制定发布的国内假日及补班时间,一般维护到数据库,每年更新一次,针对特殊日期标识【工作日】/【节假日】
- dateUnit 时间计算精确单位,天/小时/分钟/秒等
代码:
package com.test.common.util;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.Week;
import com.test.common.constant.NumberConst;
import java.util.Date;
import java.util.Map;
public class DateUtilExt {
/**
* 工作日标志
*/
private static final String WORK_DAY_FLAG_YES="1";
/**
* 非工作日标志
*/
private static final String WORK_DAY_FLAG_NO="0";
/**
* 获取工作日时间
* @param start 计算起始时间
* @param end 计算结束时间
* @param mapWorkDay 自定义节假日,例:<"2021-09-30","1"> 1-工作日,0-节假日
* @param dateUnit 返回时间精确单位
* @return
*/
public static long getWorkDayTimes(Date start, Date end, Map<String, String> mapWorkDay, DateUnit dateUnit){
if (start == null || end == null){
return 0;
}
// 如果起始日期大于结束日期,替换位置
if (DateUtil.compare(start, end) > 0){
Date temp = start;
start = end;
end = temp;
}
if (!DateUtilExt.isWorkDay(start, mapWorkDay)){
start = DateUtilExt.getNearestWorkDay(start, NumberConst.NUM_1, mapWorkDay);
}
if (!DateUtilExt.isWorkDay(end, mapWorkDay)){
end = DateUtilExt.getNearestWorkDay(end, NumberConst.NUM_NEGATIVE_1, mapWorkDay);
}
if (DateUtil.compare(start, end) > 0){
// 节假日间的,工作日耗时为0
return 0;
}
if (DateUtil.formatDate(start).equals(DateUtil.formatDate(end))){
// 如果是同一天,直接计算
return DateUtil.between(start,end, dateUnit);
}
// 非同一天,总时长-节假日时长为工作日时长
long totalTime = DateUtil.between(start, end, dateUnit);
int holidayCount = 0;
Date nextDay = DateUtil.offset(start, DateField.DAY_OF_YEAR, NumberConst.NUM_1);
holidayCount = DateUtilExt.getHolidayCount(nextDay, end, holidayCount, mapWorkDay);
long holidayTime = (holidayCount*DateUnit.DAY.getMillis())/dateUnit.getMillis();
return totalTime-holidayTime;
}
/**
* 获取时间范围内的假期天数,起始日期和结束日期均为工作日
* @param currentDate 起始日期后一天
* @param end
* @param count
* @param mapWorkDay
*/
private static int getHolidayCount(Date currentDate, Date end, int count, Map<String, String> mapWorkDay){
if (DateUtil.compare(currentDate, end) >= 0){
return count;
}
if (!DateUtilExt.isWorkDay(currentDate, mapWorkDay)){
count ++;
}
Date nextDay = DateUtil.offset(currentDate, DateField.DAY_OF_YEAR, NumberConst.NUM_1);
return DateUtilExt.getHolidayCount(nextDay, end, count, mapWorkDay);
}
/**
* 获取最近的工作日
* @param date
* @param forward 查找方向 1正向查找 -1反向查找
* @param mapWorkDay 自定义节假日
* @return
*/
private static Date getNearestWorkDay(Date date, int forward, Map<String, String> mapWorkDay){
if (DateUtilExt.isWorkDay(date, mapWorkDay)){
return date;
}
Date nextDay = DateUtil.offset(date, DateField.DAY_OF_YEAR, forward);
return DateUtilExt.getNearestWorkDay(nextDay, forward, mapWorkDay);
}
/**
* 是否是工作日
* @param date
* @param mapWorkDay 自定义节假日
* @return true-工作日 false-节假日
*/
private static boolean isWorkDay(Date date, Map<String, String> mapWorkDay){
if (!DateUtilExt.isWeekend(date)){
// 工作日
//判断是否有自定义假日
if (mapWorkDay != null && WORK_DAY_FLAG_NO.equals(mapWorkDay.get(DateUtil.formatDate(date)))){
// 自定义假日
return false;
}
// 工作日
return true;
} else {
// 节假日
// 判断是否有自定义补班
if (mapWorkDay != null && WORK_DAY_FLAG_YES.equals(mapWorkDay.get(DateUtil.formatDate(date)))){
// 自定义补班
return true;
}
// 节假日
return false;
}
}
/**
* 是否是周末
* @param date
* @return
*/
private static boolean isWeekend(Date date){
Week currentWeek = DateUtil.dayOfWeekEnum(date);
if (Week.SATURDAY.equals(currentWeek) || Week.SUNDAY.equals(currentWeek)){
return true;
}
return false;
}
}
推荐阅读
-
php计算两个日期相差天数的方法_PHP教程
-
在线一元二次方程计算器实例(方程计算器在线计算)_javascript技巧
-
线性表的链式存储结构:定义、单链表存储结构、给链表头结点分配空间、初始化链表数据、输出链表、在某个位置上插入数据、头插法、尾插法、删除某个位置上的数据、删除某个数据、删除整个链表计算链表的长度
-
php 计算3公里内所以用户的距离
-
PHP 怎么计算从某一天到某一天一共的天数然后增加?
-
vue实现简单实时汇率计算功能
-
js css 实现简易计算器_html/css_WEB-ITnose
-
php中计算未知长度的字符串哪个字符出现的次数最多的代码
-
用python脚本计算某一个文件的行数
-
计算机网络 arp