当前位置: 首页 > news >正文

获取每月最后一个工作日:考虑法定节假日与调休

在许多业务场景中,了解每个月的最后一个工作日对于财务结算、报告生成等至关重要。然而,确定这一日期时必须考虑到国家的法定节假日以及可能存在的调休安排。本文将介绍如何通过Java编写一个工具类来获取指定月份的最后一个工作日,并利用第三方免费API来处理法定节假日和调休情况。

一、准备工作

首先,你需要引入一些必要的依赖库,如Hutool用于日期操作和JSON解析,Fastjson用于简化JSON处理等。如果你使用的是Maven项目,请确保你的pom.xml文件中包含以下依赖:

<dependencies>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.11</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.78</version>
    </dependency>
</dependencies>

二、实现逻辑

1. 获取节假日数据

我们将从第三方API http://timor.tech/api/holiday/year/{year} 获取指定年份的所有节假日信息。这个API返回的数据包含了所有节假日及其是否为调休的信息。

private static Map<String, Boolean> fetchHolidays(int year) {
    Map<String, Boolean> holidayMap = new HashMap<>();
    String s = HttpUtils.sendGet("http://timor.tech/api/holiday/year/" + year);
    JSONObject jsonObject = JSONUtil.parseObj(s);
    JSONObject holidayMapJson = jsonObject.getJSONObject("holiday");
    if (Objects.isNull(holidayMapJson)) {
        return null;
    }
    // true表示是节假日,false表示是调休
    holidayMapJson.forEach((k, v) -> {
        JSONObject dayInfoObj = (JSONObject) v;
        holidayMap.put((String) dayInfoObj.get("date"), (Boolean) dayInfoObj.get("holiday"));
    });
    return holidayMap;
}

2. 计算最后的工作日

接下来,我们定义一个方法来计算给定月份的最后一个工作日,同时考虑法定节假日和调休。

public static Date getLastWorkingDayOfMonth(Map<String, Boolean> specialDays) {
    Date lastDayOfMonth = DateUtil.endOfMonth(new Date());
    Calendar calendar = DateUtil.calendar(lastDayOfMonth);

    while (!isWorkingDay(calendar, specialDays)) {
        calendar.add(Calendar.DAY_OF_MONTH, -1);
    }
    return calendar.getTime();
}

3. 判断某天是否为工作日

最后,我们需要一个辅助函数来判断某一天是否为工作日(排除周末和节假日)。

private static boolean isWorkingDay(Calendar calendar, Map<String, Boolean> specialDays) {
    int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
    String dateStr = DateUtil.format(calendar.getTime(), "yyyy-MM-dd");
    // 默认情况下,周六、周日是非工作日
    if ((dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) && !specialDays.getOrDefault(dateStr, true)) {
        // 如果这一天被特别指定为工作日,则视为工作日
        return true;
    }
    // 检查是否为法定假日或不在特殊安排中的普通周末
    return !(specialDays.containsKey(dateStr) && specialDays.get(dateStr));
}

三、测试与运行

现在,我们可以编写一个简单的主函数来测试我们的功能。

public static void main(String[] args) {
    System.out.println("本月的最后一个工作日为:" + DateUtil.format(getLastWorkingDayOfMonth(fetchHolidays(DateUtil.year(new Date()))), "yyyy-MM-dd"));
}

四、总结

通过上述步骤,我们成功地创建了一个工具类,可以方便地获取每个月的最后一个工作日,并充分考虑了法定节假日和调休的影响。这种方法不仅提高了准确性,还能灵活应对不同的业务需求变化。


全部源码如下:

package com.example.demo.util;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.example.demo.excel.constant.DimenEnum;
import com.example.demo.excel.domain.ExamineVo;
import com.example.demo.excel.util.http.HttpUtils;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Demo5 {
    public static void main(String[] args) {
        System.out.println("本月的最后一个工作日为:" + DateUtil.format(getLastWorkingDayOfMonth(fetchHolidays(DateUtil.year(new Date()))), "yyyy-MM-dd"));
    }


    /**
     * 从API获取指定年份的所有节假日
     */
    private static Map<String, Boolean> fetchHolidays(int year) {
        Map<String, Boolean> holidayMap = new HashMap<>();
        String s = HttpUtils.sendGet("http://timor.tech/api/holiday/year/" + year);
        JSONObject jsonObject = JSONUtil.parseObj(s);
        JSONObject holidayMapJson = jsonObject.getJSONObject("holiday");
        if (Objects.isNull(holidayMapJson)) {
            return null;
        }
        //true表示是节假日,false表示是调休
        holidayMapJson.forEach((k, v) -> {
            JSONObject dayInfoObj = (JSONObject) v;
            holidayMap.put((String) dayInfoObj.get("date"), (Boolean) dayInfoObj.get("holiday"));
        });
        return holidayMap;
    }


    /**
     * 计算本月的最后一个工作日,考虑到法定节假日和调休
     */
    public static Date getLastWorkingDayOfMonth(Map<String, Boolean> specialDays) {
        Date lastDayOfMonth = DateUtil.endOfMonth(new Date());
        Calendar calendar = DateUtil.calendar(lastDayOfMonth);
        while (!isWorkingDay(calendar, specialDays)) {
            calendar.add(Calendar.DAY_OF_MONTH, -1);
        }
        return calendar.getTime();
    }

    /**
     * 判断给定日期是否为工作日,考虑法定节假日和调休
     */
    private static boolean isWorkingDay(Calendar calendar, Map<String, Boolean> specialDays) {
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        String dateStr = DateUtil.format(calendar.getTime(), "yyyy-MM-dd");
        // 默认情况下,周六、周日是非工作日
        if ((dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) && !specialDays.getOrDefault(dateStr, true)) {
            // 如果这一天被特别指定为工作日,则视为工作日
            return true;
        }
        // 检查是否为法定假日或不在特殊安排中的普通周末
        return !(specialDays.containsKey(dateStr) && specialDays.get(dateStr));
    }
}


相关文章:

  • IDEA中查询Maven项目的依赖树
  • 鸿蒙初学者学习手册(HarmonyOSNext_API14)_自定义动画API(@ohos.animator (动画) )
  • RabbitMQ的脑裂(网络分区)问题
  • 推荐一款AI大模型托管平台-OpenWebUI
  • Jenkins 部署在 Mac 并在局域网内通过 ip 访问
  • 【Spring AI】简单使用示例说明
  • SAP 代码扫描工具
  • selenium爬取苏宁易购平台某产品的评论
  • 架构学习第七周--Prometheus
  • Vue 3 中如何注册全局自定义组件:一个 SVG 图标的例子
  • Debezium连接器对比
  • Unity shader glsl着色器特效之 模拟海面海浪效果
  • Python 函数(传递实参)
  • 【工具】飞书个人知识库搭建(附详细步骤)
  • 【Linux探索学习】第二十八弹——信号(下):信号在内核中的处理及信号捕捉详解
  • 理解都远正态分布中指数项的精度矩阵(协方差逆矩阵)
  • Python 3 安装与环境配置完整教程
  • 实战:如何快速让新网站被百度收录?
  • python绘图之回归拟合图
  • 【八股】计算机网络
  • 学生成绩管理系统网站建设/网络企业推广
  • 企业做响应式网站好吗/网站seo推广计划
  • 宁德北京网站建设/2345浏览器官网
  • 涟水做网站/seo日常优化内容是什么
  • 宁波做网站建设推广/最快的新闻发布平台
  • 信息推广网站点不开的那种怎么做/seo优化收费