提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
看到网上工作日的工具类不是很完整,整理了一份出来
一、获取几个工作日后的日期
1、先预置国家规定的法定节假日,和调休日(特殊工作日)
2、判断当前日期是否为工作日
二、使用步骤
1.完整代码
代码如下(示例):
package utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
/**
* @Desc:
* @Author: ding
* @Date: 2022/06/08 10:43
**/
@Slf4j
@Component
public class ComputeWorkingDayUtil {
//定义两个List,一个存放节假日日期,另一个存放调休的工作日期
private static List<String> HOLIDAY_LIST = new ArrayList<>();
private static List<String> SPECIAL_WORKDAY_LIST = new ArrayList<>();
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//静态代码块内调用第三方接口拿到数据存进List中
static {
Map<String, Object> param = new HashMap<String, Object>() {{
//这里key值是注册天行API账号是给的 天行网站申请的api-key https://www.tianapi.com/
put("key", "");
put("type", 1);
}};
//获取当前年份,循环调用3次,拿到3年的数据
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
for (int i=0; i<3; i++) {
param.put("date", currentYear - i);
String url = "http://api.tianapi.com/jiejiari/index";
String response = HttpUtil.get(url, param);
JSONObject resObj = JSONUtil.parseObj(response);
int code = (int) resObj.get("code");
if (code == 200) {
JSONArray newslist = (JSONArray) resObj.get("newslist");
for (Object listObj : newslist) {
JSONObject obj = (JSONObject) listObj;
String holidays = (String) obj.get("vacation");
String[] holidayArray = holidays.split("\\|");
HOLIDAY_LIST.addAll(Arrays.asList(holidayArray));
String remark = (String) obj.get("remark");
if (StringUtils.isNotEmpty(remark)) {
String[] special = remark.split("\\|");
SPECIAL_WORKDAY_LIST.addAll(Arrays.asList(special));
}
}
}else {
log.info("调用第三方天行api接口获取节假日信息失败,请注意年底前维护次年节假日和调休日数据!");
// 如果请求第三方网站api接口数据失败,则需要 每年12月份左右等国务院公告 提前手动录入每年的法定节假日和调休日
String holidays = "2022-01-01,2022-01-02,2022-01-03,2022-01-31,2022-02-01,2022-02-02,2022-02-03,2022-02-04,2022-02-05,2022-02-06," +
"2022-04-03,2022-04-04,2022-04-05,2022-04-30,2022-05-01,2022-05-02,2022-05-03,2022-05-04,2022-06-03,2022-06-04,2022-06-05," +
"2022-09-10,2022-09-11,2022-09-12,2022-10-01,2022-10-02,2022-10-03,2022-10-04,2022-10-05,2022-10-06,2022-10-07";
String specialWorkdays = "2022-01-29,2022-01-30,2022-04-02,2022-04-24,2022-05-27,2022-10-08,2022-10-09";
// 转化为数组
String[] holidaysArr = holidays.split(",");
String[] specialWorkdaysArr = specialWorkdays.split(",");
HOLIDAY_LIST = new ArrayList<>(Arrays.asList(holidaysArr));
SPECIAL_WORKDAY_LIST = new ArrayList<>(Arrays.asList(specialWorkdaysArr));
break;
}
}
}
//计算工作日数的方法
public static int computeWorkingDays(Date start, Date end) {
Calendar startCal = Calendar.getInstance();
Calendar endCal = Calendar.getInstance();
startCal.setTime(start);
endCal.setTime(end);
int workDays = 0;
//如果没有严格按照起始结束时间传值,在这里纠正下,可以注释掉
if (startCal.getTimeInMillis() > endCal.getTimeInMillis()) {
startCal.setTime(end);
endCal.setTime(start);
}
while (startCal.getTimeInMillis() <= endCal.getTimeInMillis()) {
//控制台打印出来循环情况,方便查看
//System.out.println(DateUtil.format(startCal.getTime(), "yyyy-MM-dd") + " " + DateUtil.format(endCal.getTime(), "yyyy-MM-dd"));
String current = DateUtil.format(startCal.getTime(), "yyyy-MM-dd");
int dayOfWeek = startCal.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY)
{
if (!HOLIDAY_LIST.contains(current)) {
System.out.println(true);
workDays++;
}
}
if (SPECIAL_WORKDAY_LIST.contains(current)) {
System.out.println(true);
workDays++;
}
startCal.add(Calendar.DATE, 1);
}
return workDays;
}
/**
* 获取n个工作日后的日期
* @param today opening date
* @param num num个工作日后
* @return
* @throws ParseException
*/
public static Date getScheduleActiveDate(Date today, int num) throws ParseException {
int delay = 1;
while(delay <= num){
Date tomorrow = getTomorrow(today);
String tomorrowStr = sdf.format(tomorrow);
//当前日期+1,判断是否是节假日,不是的同时要判断是否是周末,都不是则scheduleActiveDate日期+1
if((!isWeekend(tomorrowStr) && !isHoliday(tomorrowStr,HOLIDAY_LIST))
|| isExtraWorkdays(tomorrowStr,SPECIAL_WORKDAY_LIST)){
delay++;
today = tomorrow;
} else if (isWeekend(tomorrowStr)){
today = tomorrow;
} else if (isHoliday(tomorrowStr,HOLIDAY_LIST)){
today = tomorrow;
}
}
return today;
}
/**
* 获取n个工作日前的日期
* @param today opening date
* @param num num个工作日后
* @return
* @throws ParseException
*/
public static Date getScheduleActiveDateBefore(Date today, int num) throws ParseException {
int delay = 1;
while(delay <= num){
Date yesterday = getYesterday(today);
String tomorrowStr = sdf.format(yesterday);
//当前日期+1,判断是否是节假日,不是的同时要判断是否是周末,都不是则scheduleActiveDate日期+1
if((!isWeekend(tomorrowStr) && !isHoliday(tomorrowStr,HOLIDAY_LIST))
|| isExtraWorkdays(tomorrowStr,SPECIAL_WORKDAY_LIST)){
delay++;
today = yesterday;
} else if (isWeekend(tomorrowStr)){
today = yesterday;
} else if (isHoliday(tomorrowStr,HOLIDAY_LIST)){
today = yesterday;
}
}
return today;
}
/**
* 获取tomorrow的日期
*
* @param date
* @return
*/
public static Date getTomorrow(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, +1);
date = calendar.getTime();
return date;
}
/**
* 获取yesterday的日期
*
* @param date
* @return
*/
public static Date getYesterday(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, -1);
date = calendar.getTime();
return date;
}
/**
* 判断是否是weekend
*
* @param sdate
* @return
* @throws ParseException
*/
public static boolean isWeekend(String sdate) throws ParseException {
Date date = sdf.parse(sdate);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
return true;
} else{
return false;
}
}
/**
* 判断是否是holiday
*
* @param sdate
* @param list
* @return
* @throws ParseException
*/
public static boolean isHoliday(String sdate, List<String> list) throws ParseException {
if(list.size() > 0){
for(int i = 0; i < list.size(); i++){
if(sdate.equals(list.get(i))){
return true;
}
}
}
return false;
}
/**
* 判断是否是由于放假需要额外工作的周末
*
* @param sdate
* @param list
* @return
* @throws ParseException
*/
public static boolean isExtraWorkdays(String sdate, List<String> list) throws ParseException {
if(list.size() > 0){
for(int i = 0; i < list.size(); i++){
if(sdate.equals(list.get(i))){
return true;
}
}
}
return false;
}
public static Boolean isWorkingDay(Date date) {
LocalDateTime localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
String dateStr = sdf.format(date);
//是否加班日
if(SPECIAL_WORKDAY_LIST.contains(dateStr)){
return true;
}
//是否节假日
if(HOLIDAY_LIST.contains(dateStr)){
return false;
}
//如果是1-5表示周一到周五 是工作日
DayOfWeek week = localDate.getDayOfWeek();
if(week==DayOfWeek.SATURDAY||week==DayOfWeek.SUNDAY){
return false;
}
return true;
}
public static void main(String[] args) throws Exception {
Date workDay = getScheduleActiveDateBefore(new Date(),2);
Calendar cal = Calendar.getInstance();
cal.setTime(workDay);
cal.add(Calendar.HOUR,23);
cal.add(Calendar.MINUTE,59);
cal.add(Calendar.SECOND,59);
System.out.println(workDay);
}
}
总结
个人整理的比较粗糙