我有以下方法,其中我有startDate
和endDate
类型的字符串yyyy/mm/dd
。我想要返回List<LocalDate>
protected List<LocalDate> getDateList(String startDate, String endDate) {
//build list here
}
如何在Java 8中执行此操作?
答案 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());
}