做一个实用的节假日工具

前言

在日常开发中,我们经常需要判断某一天是工作日还是休息日。

遗憾的是,常见工具类库中并没有直接提供"节假日判断"的功能。原因在于:中国的节假日安排由国务院每年统一发布,存在动态性和不确定性

因此,一个可行的方案是:维护一份节假日数据,并封装成工具类供项目调用 。下面我分享一个基于 Java + JSON + 定时检测 的实现方案。


原理说明

  1. 数据来源:国务院每年 11 月前后会发布次年的节假日安排;

  2. 数据格式 :节假日信息经过处理后保存为 JSON 文件

  3. 工具类逻辑

    • 启动时加载 2007 年至今的节假日数据;
    • 提供方法 isRestDay / isWorkDay 判断某天状态;
    • 默认规则:如果当天未配置,则按周六日为休息日。
  4. 提醒机制 :通过单元测试或定时任务,在 12 月份自动检查下一年节假日文件是否存在,避免遗漏。


代码实现

1. 测试类:检测是否加载节假日数据

java 复制代码
@Test
void testHolidayStatus() {
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
    final int monthValue = now.getMonthValue();

    // 如果当前时间是12月,则优先检查下一年的节假日数据
    int currentYear = monthValue == 12 ? now.getYear() + 1 : now.getYear();
    System.out.printf("startYear:%s, currentYear:%s, 一共%s年%n", 
        HolidayUtil.START_YEAR, currentYear, currentYear - HolidayUtil.START_YEAR + 1);

    for (int year = HolidayUtil.START_YEAR; year <= currentYear; year++) {
        DateTime holiday = DateUtil.parse(String.format("%s-10-01", year));
        if (Objects.isNull(HolidayUtil.getHolidayStatus(holiday))) {
            throw new RuntimeException(String.format("当前已到12月,请补充【%s】年的放假文件", year));
        }
        assertTrue(HolidayUtil.isRestDay(holiday));
    }

    System.out.println(HolidayUtil.isRestDay(DateUtil.parse("2025-09-28")));
}

2. 工具类:HolidayUtil

java 复制代码
public class HolidayUtil {

    private static final Map<String, Boolean> HOLIDAY_MAP = new HashMap<>();
    public static final int START_YEAR = 2007;

    static {
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        int currentYear = now.getYear();
        for (int year = START_YEAR; year <= currentYear; year++) {
            loadYear(year);
        }
    }

    @SneakyThrows
    public static void loadYear(int year) {
        String fileName = String.format("holiday/%d.txt", year);
        URL resource = HolidayUtil.class.getClassLoader().getResource(fileName);
        if (resource == null) {
            throw new RuntimeException("未找到节假日文件: " + fileName);
        }
        try (InputStream is = new FileInputStream(new File(resource.toURI()))) {
            ObjectMapper mapper = new ObjectMapper();
            List<Map<String, Object>> list = mapper.readValue(is, new TypeReference<>() {});
            for (Map<String, Object> item : list) {
                HOLIDAY_MAP.put((String) item.get("date"), (Boolean) item.get("holiday"));
            }
        }
    }

    public static Boolean getHolidayStatus(DateTime date) {
        return HOLIDAY_MAP.get(date.toDateStr());
    }

    public static boolean isRestDay(DateTime date) {
        Boolean status = getHolidayStatus(date);
        if (status != null) return status;
        return date.dayOfWeekEnum() == DateTime.DayOfWeek.SATURDAY
            || date.dayOfWeekEnum() == DateTime.DayOfWeek.SUNDAY;
    }

    public static boolean isWorkDay(DateTime date) {
        return !isRestDay(date);
    }
}

节假日数据格式

节假日数据维护为 JSON 文件,结构如下:

json 复制代码
[
  { "date": "2025-01-01", "holiday": true },
  { "date": "2025-01-26", "holiday": false },
  { "date": "2025-02-08", "holiday": false },
  { "date": "2025-05-01", "holiday": true },
  { "date": "2025-09-28", "holiday": false }
]
  • holiday = true → 表示节假日/休息日
  • holiday = false → 表示调休上班

检测机制

为了避免忘记维护数据,可以在单元测试或定时任务中加入 文件存在性检查

比如在每年 12 月,检查下一年的文件是否存在,如果不存在就抛出异常提醒。


总结

本文实现了一个简易的 节假日判断工具类,其核心思路是:

  • 通过维护每年的国务院放假数据(JSON 文件);
  • 在工具类中加载并判断日期状态;
  • 加入提醒机制,保证节假日数据及时更新。

这个工具可以广泛应用在:

  • OA 系统请假审批
  • 考勤/排班计算
  • 财务/薪资发放逻辑

简单易用,但实用性很强。 🚀


相关推荐
李白同学2 小时前
C++:list容器--模拟实现(下篇)
开发语言·数据结构·c++·windows·算法·list
一丢沙2 小时前
Verilog 硬件描述语言自学——重温数电之典型组合逻辑电路
开发语言·算法·fpga开发·verilog
Funcy3 小时前
XxlJob源码分析01:环境准备
java
the beard3 小时前
Feign整合Sentinel实现服务降级与Feign拦截器实战指南
java·spring·sentinel
炒毛豆3 小时前
vue3+antd实现华为云OBS文件拖拽上传详解
开发语言·前端·javascript
THMAIL3 小时前
攻克 Java 分布式难题:并发模型优化与分布式事务处理实战指南
java·开发语言·分布式
完美世界的一天3 小时前
Golang 面试题「中级」
开发语言·后端·面试·golang
小沈同学呀4 小时前
使用Java操作微软 Azure Blob Storage:上传和下载文件
java·microsoft·azure
Morpheon5 小时前
Intro to R Programming - Lesson 4 (Graphs)
开发语言·r语言
代码AI弗森5 小时前
使用 JavaScript 构建 RAG(检索增强生成)库:原理与实现
开发语言·javascript·ecmascript