自定义TemporalAdjuster实现“逢节假日顺延到下一个工作日”,需封装跳过周末和法定放假日的逻辑,通过实现adjustInto方法并结合offDays集合与isWorkingDay判断完成。

自定义 TemporalAdjuster 实现“逢节假日顺延到下一个工作日”(即跳过周末和法定假日),核心在于封装一个能识别节假日、跳过非工作日的日期调整逻辑。Java 8+ 的 TemporalAdjuster 是函数式接口,只需实现 adjustInto(Temporal) 方法即可。
明确节假日与工作日的判定规则
Java 原生不提供法定节假日数据,需自行维护或接入外部服务。常见规则包括:
- 周一至周五为工作日(排除周末)
- 国家法定节假日(如春节、国庆等)视为非工作日,需跳过
- 调休上班的节假日(如周六上班)应视为工作日(需额外标记)
- 顺延方向:通常向后顺延(如遇节假,取下一个工作日),也可支持向前/就近(按业务定)
定义节假日数据源(轻量级示例)
用 Set<LocalDate> 模拟静态节假日列表(生产环境建议从配置文件、数据库或 HTTP API 加载):
private static final Set<LocalDate> HOLIDAYS = Set.of(
LocalDate.of(2024, 1, 28), // 春节前调休上班?→ 这里仅为示例,实际需区分“放假日”和“调休上班日”
LocalDate.of(2024, 2, 10), // 春节放假起始日
LocalDate.of(2024, 2, 17), // 春节放假结束日
LocalDate.of(2024, 10, 1), // 国庆首日
LocalDate.of(2024, 10, 7) // 国庆末日
);
⚠️ 注意:真实场景中需区分「放假日」和「调休上班日」。例如 2024 年 2 月 4 日(周日)被调为上班日,它应 不参与顺延跳过。建议用两个集合:OFF_DAYS(放假日)和 WORK_ON_WEEKEND(周末上班日)。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
编写自定义 TemporalAdjuster(向后顺延)
以下是一个简洁、可复用的实现,支持跳过周末 + 法定放假日:
public class NextWorkingDayAdjuster implements TemporalAdjuster {
private final Set<LocalDate> offDays;
public NextWorkingDayAdjuster(Set<LocalDate> offDays) {
this.offDays = offDays != null ? offDays : Set.of();
}
@Override
public Temporal adjustInto(Temporal temporal) {
LocalDate date = LocalDate.from(temporal);
LocalDate result = date;
do {
result = result.plusDays(1);
} while (!isWorkingDay(result));
return temporal.with(result);
}
private boolean isWorkingDay(LocalDate d) {
DayOfWeek dow = d.getDayOfWeek();
if (dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY) {
return false;
}
if (offDays.contains(d)) {
return false;
}
return true;
}
}
使用方式:
LocalDate input = LocalDate.of(2024, 2, 10); // 春节放假第一天 LocalDate nextWorkDay = input.with(new NextWorkingDayAdjuster(HOLIDAYS)); // → 返回 2024-02-19(假设 2.10~2.17 放假,2.18 周日,2.19 周一)
进阶建议:支持调休、可配置方向、线程安全
生产可用的版本可进一步增强:
-
支持调休识别:在
isWorkingDay()中增加对WORK_ON_WEEKEND集合的检查,若某周六在该集合中,则返回true -
支持顺延方向:构造时传入
Direction.NEXT/Direction.PREVIOUS/Direction.CLOSEST,分别实现向后、向前、或比较前后距离选近者 -
避免重复计算:将节假日集合转为
TreeSet或预构建布尔数组(适合固定年份),提升contains()性能 -
线程安全:所有字段 final,集合不可变(用
Set.copyOf()或ImmutableSet),adjuster 实例可全局复用
不复杂但容易忽略细节,关键是把“什么是工作日”的判断逻辑写清楚、可维护、可测试。

















