java获取工作日工具类

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

看到网上工作日的工具类不是很完整,整理了一份出来


一、获取几个工作日后的日期

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);
    }

}

总结

个人整理的比较粗糙

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值