1. 概述

Java 8 引入的全新时间 API 让日期时间处理不再依赖外部库。这篇短文将对比不同 Java 版本中获取两个日期之间所有日期的实现方式,看看它们是如何逐步简化的。

2. 使用 Java 7

在 Java 7 中,我们需要借助 Calendar 实现这个功能。核心思路是:

  1. 先获取去除时间信息的开始和结束日期
  2. 通过循环逐天递增,直到达到结束日期

以下是具体实现代码:

public static List getDatesBetweenUsingJava7(Date startDate, Date endDate) {
  List datesInRange = new ArrayList<>();
  Calendar calendar = getCalendarWithoutTime(startDate);
  Calendar endCalendar = getCalendarWithoutTime(endDate);

  while (calendar.before(endCalendar)) {
    Date result = calendar.getTime();
    datesInRange.add(result);
    calendar.add(Calendar.DATE, 1);
  }

  return datesInRange;
}

private static Calendar getCalendarWithoutTime(Date date) {
  Calendar calendar = new GregorianCalendar();
  calendar.setTime(date);
  calendar.set(Calendar.HOUR, 0);
  calendar.set(Calendar.HOUR_OF_DAY, 0);
  calendar.set(Calendar.MINUTE, 0);
  calendar.set(Calendar.SECOND, 0);
  calendar.set(Calendar.MILLISECOND, 0);
  return calendar;
}

⚠️ 这种方式需要手动处理时间清零和循环控制,代码量较大且容易出错。

3. 使用 Java 8

Java 8 的 Stream API 让实现变得优雅许多:

  1. 先计算两个日期间的天数差
  2. 创建整数流并映射为日期对象
  3. 收集结果到列表
public static List<LocalDate> getDatesBetweenUsingJava8(
  LocalDate startDate, LocalDate endDate) { 
 
    long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate); 
    return IntStream.iterate(0, i -> i + 1)
      .limit(numOfDaysBetween)
      .mapToObj(i -> startDate.plusDays(i))
      .collect(Collectors.toList()); 
}

✅ 关键改进:

  • 使用 ChronoUnit.DAYS.between() 精确计算天数
  • 通过 IntStreammapToObj 实现函数式转换
  • 避免了手动循环和状态管理

4. 使用 Java 9

Java 9 提供了终极解决方案——直接使用 datesUntil() 方法:

public static List<LocalDate> getDatesBetweenUsingJava9(
  LocalDate startDate, LocalDate endDate) {
 
    return startDate.datesUntil(endDate)
      .collect(Collectors.toList());
}

✅ 核心优势:

  • 单行代码完成核心逻辑
  • datesUntil() 直接返回有序日期流
  • 无需手动计算天数差或创建中间流

5. 总结

对比三个版本的实现,我们可以清晰看到 Java 时间 API 的演进:

  1. Java 7:需要手动处理 Calendar 和循环,代码冗长
  2. Java 8:通过 Stream API 实现函数式风格,显著简化
  3. Java 9:专用方法 datesUntil() 提供最简洁方案

对于新项目,强烈推荐使用 Java 9+ 的方案。如果仍在使用 Java 8,Stream 方式也是不错的选择。至于 Java 7 的实现方式,建议在升级时尽快替换。

完整代码示例可在 GitHub 查看。


原始标题:How to Get All Dates Between Two Dates?