
本文介绍使用 Java 9+ 的 LocalDate.datesUntil() 方法,高效生成给定起止日期间所有周一(广播周起始日)的 LocalDate 列表,避免手动循环,代码简洁且线程安全。
本文介绍使用 java 9+ 的 `localdate.datesuntil()` 方法,高效生成给定起止日期间所有周一(广播周起始日)的 `localdate` 列表,避免手动循环,代码简洁且线程安全。
在广播日历(Broadcast Calendar)中,每周统一以周一为起始日,因此业务常需提取某时间段内全部周一日期(如用于广告排期、收视率统计等)。给定范围 2024-10-07 至 2024-12-29,目标是精确获取该区间内所有周一(含边界),即:2024-10-07, 2024-10-14, 2024-10-21, …, 2024-12-23(共 12 个日期)。
关键在于:起始日期必须是周一,否则 datesUntil(..., Period.ofWeeks(1)) 会从非周一出发,导致结果偏移。因此,推荐先将起始日期“对齐”到最近的周一(不晚于原日期),再执行遍历:
import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.Period;
import java.util.List;
public class BroadcastMondayExtractor {
public static List<LocalDate> getMondaysInRange(LocalDate startInclusive, LocalDate endInclusive) {
// 确保起始日为周一:若非周一,则回退至本周一
LocalDate alignedStart = startInclusive.with(DayOfWeek.MONDAY);
if (alignedStart.isAfter(startInclusive)) {
alignedStart = alignedStart.minusWeeks(1);
}
// 使用 datesUntil 生成每周一的流(步长为 1 周),并包含结束日(需 +1 天确保覆盖)
return alignedStart.datesUntil(endInclusive.plusDays(1), Period.ofWeeks(1))
.filter(date -> !date.isBefore(startInclusive) && !date.isAfter(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 = getMondaysInRange(start, end);
mondays.forEach(System.out::println);
// 输出:2024-10-07, 2024-10-14, ..., 2024-12-23(共12个)
}
}✅ 优势说明:
-
datesUntil()返回惰性求值的Stream<localdate></localdate>,内存友好; -
Period.ofWeeks(1)确保严格按自然周推进,天然适配广播日历逻辑; - 配合
filter()可精准控制边界(尤其当起始日非周一时),比简单while循环更健壮。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 此方案要求 Java 9 或更高版本(
datesUntil是 Java 9 引入); - 若项目仍使用 Java 8,应改用
TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)配合while循环实现; -
endInclusive.plusDays(1)是为确保datesUntil能包含末尾周一(该方法默认不包含终点); - 所有操作基于不可变
LocalDate,线程安全,无需额外同步。
通过此方法,你可快速、可靠地构建广播日历的周一序列,为后续排期计算、数据分组等场景提供坚实基础。


















