java.time
Answer by Dónal using Joda-Time 是正确的,但已过时。 Joda-Time 团队建议我们应该迁移到 Java 8 及更高版本中内置的 java.time 框架。大部分 java.time 功能已被 back-ported to Java 6 & 7 和进一步 adapted to Android。
LocalDate
对于仅日期值、没有时间和时区,请使用 LocalDate 类。
半开
通常,处理时间跨度的最佳做法称为半开。在这种方法中,span 的开头是inclusive,而结尾是exclusive。因此,使用下面的示例代码,您将看到结果不包括 stop 日期。如果您坚持包含结尾,请将date.isBefore ( stop ) 更改为! date.isAfter ( stop )。
示例代码
在目前的状态下,该问题是模糊的,没有解决诸如是否考虑开始日期恰好与周开始或月开始等问题。另一个问题:是否使用半开方法。所以这些问题留给读者作为练习。 ;-)
此代码计算时间跨度中的天数。如果不到一周,我们会每天循环。如果超过一周,我们会逐周循环。可以将相同的逻辑扩展到处理问题中提到的逐月、逐季度和逐年。
LocalDate start = LocalDate.of ( 2016 , Month.JANUARY , 2 );
LocalDate stop = start.plusDays ( 4 );
// LocalDate stop = start.plusWeeks ( 4 );
long days = ChronoUnit.DAYS.between ( start , stop );
List<LocalDate> dates = new ArrayList<> ();
if ( days == 0 ) {
dates.add ( start );// Just one date, as start equals stop.
} else if ( days < 7 ) { // Under a week, count day-by-day.
LocalDate date = start;
do {
dates.add ( date );
// Prep for next loop.
date = date.plusDays ( 1 );
} while ( date.isBefore ( stop ) ); // Using “isBefore” for Half-Open approach where ending is exclusive. For inclusive, use “! isAfter”.
} else if ( days > 7 ) { // Over a week, count week-by-week.
LocalDate date = start;
do {
dates.add ( date );
// Prep for next loop.
date = date.plusWeeks ( 1 );
} while ( date.isBefore ( stop ) ); // Using “isBefore” for Half-Open approach where ending is exclusive. For inclusive, use “! isAfter”.
} else {
// FIXME: ERROR. Should not be possible.
}
转储到控制台。
System.out.println ( "start: " + start + " | stop: " + stop + " | dates: " + dates );
当使用stop 的行运行时添加 4 个天:
开始:2016-01-02 |停止:2016-01-06 |日期:[2016-01-02、2016-01-03、2016-01-04、2016-01-05]
当使用stop 的行运行时,增加 4 个周:
开始:2016-01-02 |停止:2016-01-30 |日期:[2016-01-02、2016-01-09、2016-01-16、2016-01-23]