Java 8 的 TemporalAdjusters 提供不可变的日期时间调整功能,支持月末月初、周相关、月内第几个某日、年相关等内置调整器,并可通过 with() 方法配合 LocalDate 等使用,也支持 lambda 自定义。

Java 8 引入的 java.time API 提供了强大且易用的日期时间处理能力,其中 TemporalAdjusters 是专门用于“调整”日期时间的工具类。它不直接修改对象,而是返回一个调整后的新实例(因为所有 java.time 类都是不可变的)。掌握它能让你轻松实现诸如“本月最后一天”“下个周一”“当月第一个工作日”等常见业务逻辑。
常用内置调整器怎么用
TemporalAdjusters 提供了一系列静态工厂方法,覆盖大多数日常需求:
-
月末/月初:
TemporalAdjusters.lastDayOfMonth()返回当月最后一天;TemporalAdjusters.firstDayOfMonth()返回当月第一天。 -
周相关:
TemporalAdjusters.next(DayOfWeek.MONDAY)找下一个周一(不含当天);TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY)找本周或下周的周五;TemporalAdjusters.previous(DayOfWeek.SUNDAY)找上一个周日。 -
月内第几个某日:
TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.WEDNESDAY)表示本月第二个周三。 -
年相关:
TemporalAdjusters.firstDayOfNextYear()、TemporalAdjusters.lastDayOfYear()等也一并支持。
配合 LocalDate / LocalDateTime 使用
所有调整器都通过 with() 方法应用。注意:只能对实现了 Temporal 接口的类型(如 LocalDate、LocalDateTime、ZonedDateTime)调用。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
例如:
立即学习“Java免费学习笔记(深入)”;
LocalDate today = LocalDate.now();LocalDate nextFriday = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));
LocalDate lastDayOfMarch = LocalDate.of(2024, 3, 1).with(TemporalAdjusters.lastDayOfMonth());
自定义调整器(简单场景)
如果内置不够用,可以实现 TemporalAdjuster 接口,或更简单地用 lambda 表达式。比如“本月倒数第三个工作日”:
LocalDate date = LocalDate.from(temporal);
LocalDate end = date.with(TemporalAdjusters.lastDayOfMonth());
int count = 0;
while (count if (end.getDayOfWeek().getValue() <= 5) count++;
if (count == 3) break;
end = end.minusDays(1);
}
return end;
};
LocalDate result = LocalDate.now().with(thirdLastWorkday);
注意事项和小技巧
-
线程安全:所有内置
TemporalAdjusters都是单例、无状态的,可安全共享使用。 -
不可变性:每次
with()都返回新对象,原对象不变 —— 这是设计原则,不是 bug。 -
时区无关:
TemporalAdjusters本身不处理时区,但可用于ZonedDateTime(调整的是本地时间部分,时区保持不变)。 -
链式调用:可连续使用多个
with(),比如date.with(firstDayOfMonth).with(nextOrSame(MONDAY))表示“本月第一个周一”。

















