计算工作日时长
工具类说明:
- 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";
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){
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;
}
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);
}
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);
}
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;
}
}
private static boolean isWeekend(Date date){
Week currentWeek = DateUtil.dayOfWeekEnum(date);
if (Week.SATURDAY.equals(currentWeek) || Week.SUNDAY.equals(currentWeek)){
return true;
}
return false;
}
}