工作日时长"/>
计算工作日时长
计算工作日时长
工具类说明:
- 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){// 节假日间的,工作日耗时为0return 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;}
}
更多推荐
计算工作日时长
发布评论