
本文介绍如何使用 Java 9+ 的 LocalDate.datesUntil() 方法,高效生成给定日期区间内所有周一(广播日历周起始日)的日期列表,避免手动循环计算,代码简洁且线程安全。
本文介绍如何使用 java 9+ 的 `localdate.datesuntil()` 方法,高效生成给定日期区间内所有周一(广播日历周起始日)的日期列表,避免手动循环计算,代码简洁且线程安全。
在广播日历(Broadcast Calendar)中,每周从周一(Monday)开始,因此常需提取某段时间内所有周一对应的日期。例如,给定范围 2024-10-07 至 2024-12-29,目标是准确获取该区间内每个周一的 LocalDate,如:2024-10-07、2024-10-14、…、2024-12-23。
Java 9 引入的 LocalDate.datesUntil(end, period) 方法为此类需求提供了原生支持:它返回一个 Stream<localdate></localdate>,按固定周期(如每周)从起始日递增至结束日(不含结束日)。关键前提是——起始日期必须是目标星期几(此处为周一)。若原始起始日非周一,需先将其“对齐”到最近的周一(向前或向后调整),再调用 datesUntil。
以下为完整、健壮的实现示例:
import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.Period;
import java.util.List;
public class BroadcastMondayExtractor {
/**
* 获取指定日期范围内所有周一的日期列表(含起始周一,不含超过 end 的周一)
* @param startInclusive 起始日期(含)
* @param endInclusive 结束日期(含)
* @return 按升序排列的周一 LocalDate 列表
*/
public static List<LocalDate> getAllMondays(LocalDate startInclusive, LocalDate endInclusive) {
// 将起始日对齐到当周周一(若 startInclusive 是周一,则保持不变;否则取前一个周一)
LocalDate firstMonday = startInclusive.with(DayOfWeek.MONDAY);
if (firstMonday.isAfter(startInclusive)) {
firstMonday = firstMonday.minusWeeks(1); // 向前调整一周
}
// datesUntil 不包含 end,因此将 endInclusive 向后扩展一天,确保覆盖最后一个可能的周一
LocalDate adjustedEnd = endInclusive.plusDays(1);
return firstMonday.datesUntil(adjustedEnd, Period.ofWeeks(1))
.filter(date -> !date.isAfter(endInclusive)) // 显式过滤,确保不超出 endInclusive
.toList();
}
// 使用示例
public static void main(String[] args) {
LocalDate start = LocalDate.of(2024, 10, 7);
LocalDate end = LocalDate.of(2024, 12, 29);
List<LocalDate> mondays = getAllMondays(start, end);
System.out.println(mondays);
// 输出:[2024-10-07, 2024-10-14, ..., 2024-12-23]
}
}✅ 注意事项与最佳实践:
立即学习“Java免费学习笔记(深入)”;
-
datesUntil返回的 Stream 是惰性求值的,toList()会触发终端操作并收集结果;如需流式处理(如分页、映射为字符串),可直接链式调用map()或forEach()。 - 原始代码中使用
new Date(String)已过时且线程不安全,应完全避免;推荐统一使用LocalDate/ZonedDateTime等现代时间 API。 - 若输入日期范围较小(如少于 100 天),性能差异可忽略;但
datesUntil相比传统while循环更语义清晰、不易出错。 - 广播日历虽有特殊季度划分规则,但“周起始为周一”这一约定与 ISO 周一致,故
DayOfWeek.MONDAY完全适用,无需额外日历系统集成。
综上,利用 LocalDate.datesUntil() 是获取连续周一日期最简洁、标准且可读性强的 Java 解决方案。


















