使用 java.time
Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。
半开
日期时间工作通常使用半开方法来定义一个时间跨度,其中开始是包含,结束是不包含。我相信在您的代码和用户业务中一致使用这种方法会使生活变得更加轻松,避免可能导致误解或错误的歧义。
java.time 类使用半开方法。在使用 Period、Duration 和 ChronUnit 类时请记住这一点。
LocalDate start = LocalDate.of( 2017 , 1 , 23 );
LocalDate stop = LocalDate.of( 2017 , 2 , 14 );
List<LocalDate> dates = new ArrayList<>( (int) ChronoUnit.DAYS.between( start , stop ) ) ;
LocalDate ld = start ;
while( ld.isBefore( stop ) ) { // Half-open approach, ending is exclusive.
dates.add( ld );
// Set up the next loop.
ld = ld.plusDays( 1 );
}
如果您坚持包含该结束日期,请在输入中添加一天。
LocalDate stop = LocalDate.of( 2017 , 2 , 14 ).plusDays( 1 ); // Effectively making ending date inclusive.
…或者 (A) 将 while 测试的逻辑从 isBefore 更改为 ! isAfter,并且 (B) 在 ArrayList 的初始容量上加一。
List<LocalDate> dates = new ArrayList<>( ( (int) ChronoUnit.DAYS.between( start , stop ) ) + 1 ) ; // Add one to accommodate inclusive ending (*not* Half-Open).
LocalDate ld = start ;
while( ! ld.isAfter( stop ) ) { // Ending is inclusive (*not* Half-Open). So using "not after" logic rather than "is before".
dates.add( ld );
// Set up the next loop.
ld = ld.plusDays( 1 );
}
Stream<LocalDate>
顺便说一句,这段代码在 Java 9 中变得更简单了,您可以从 LocalDate::datesUntil 方法中获取 Stream<LocalDate。该调用返回一个按顺序排列的日期流。
该方法的一个变体允许您指定增加日期的数量。因此,例如,您可以增加 2 以获得每隔一天的增量,而不是默认的单天增量。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。