如何从给定范围构建LocalDate列表?

kos*_*sta 5 java date list java-8 java-stream

我有以下方法,其中我有startDateendDateString类型yyyy/mm/dd.我想回来一个List<LocalDate>

protected List<LocalDate> getDateList(String startDate, String endDate) {

//build list here

}
Run Code Online (Sandbox Code Playgroud)

我怎样才能在Java 8中做到这一点?

Grz*_*rek 15

假设您的输入数据正确,我们可以使用Stream API生成给定范围内的所有日期:

final LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
final LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy/MM/dd"));

final int days = (int) start.until(end, ChronoUnit.DAYS);

return Stream.iterate(start, d -> d.plusDays(1))
  .limit(days)
  .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

例:

getDateList("2012/10/10", "2012/10/12")

[2012-10-10, 2012-10-11]

如果要包含结束日期,则需要使用.limit(days + 1).


从Java 9开始,可以将其简化为:

Stream.iterate(start, d -> d.plusDays(1))
  .takeWhile(d -> d.isBefore(end))
  .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

请记住确保正确处理包含最后日期.

  • _“从 Java 9 开始,可以将其简化为...”_ - 或者仅使用 [LocalDate.datesUntil()](https://docs.oracle.com/en/java/javase/13/docs/api /java.base/java/time/LocalDate.html#datesUntil(java.time.LocalDate)) (2认同)

Mag*_*lex 5

接受的答案是正确的,一个好.

但是,有一种替代解决方案,我们创建了LongStream超过几天.这里rangeClosed()确保创建一个包含最后一天的longs流.range()如果最后一天不应包含在列表中,请更换.

与pivovarit提出的解决方案相比,这样做的好处是我们不需要将其转换longint.此外,由于我们可以使用rangeClosed()或者range(),我们不需要days + 1包含/排除最后日期的技巧:

public List<LocalDate> toDateList(String startDate, String endDate) {
  final LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
  final LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy/MM/dd"));

  final long days = start.until(end, ChronoUnit.DAYS);

  return LongStream.rangeClosed(0, days)
      .mapToObj(start::plusDays)
      .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)