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

时间:2016-11-18 07:36:40

标签: java list date java-8 java-stream

我有以下方法,其中我有startDateendDate类型的字符串yyyy/mm/dd。我想要返回List<LocalDate>

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

//build list here

}

如何在Java 8中执行此操作?

2 个答案:

答案 0 :(得分:13)

假设您的输入数据正确,我们可以使用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());

示例:

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());

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

答案 1 :(得分:5)

accepted answer是正确的,也是一个好的。

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

与pivovarit提出的解决方案相比,这样做的好处是我们不需要将long向下转换为int。此外,由于我们可以使用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());
}