您的问题不清楚,但显然您想查找该月最后一天恰好是星期一的所有事件。
java.time
现代方法使用 java.time 类。具体来说,LocalDate 类表示没有时间和时区的仅日期值。还有 Year 和 YearMonth 和 DayOfWeek 类,顾名思义。
您可以传递 Year 对象以确保类型安全,而不是仅传递整数,从而使您的代码更具自我记录性。
Year startYear = Year.of( 2016 );
Year stopYear = Year.of( 2018 );
定义你的实用方法。
public List< LocalDate > calcMondays ( Year startYear , Year stopYear ) { … }
传递那对对象。
List< LocalDate> dates = this.calcMondays( startYear , stopYear ) ;
我建议始终使用半开放方法来定义时间跨度。在这种方法中,开头是inclusive,而结尾是exclusive。因此,2017-2019 年期间将从 2017 年的第一天开始,一直持续到但不包括 2019 年的第一天,为期 2 年。
获取开始和结束的YearMonth,代表整个月份。
YearMonth startYm = YearMonth.from( startYear.atDay( 1 ) ) ;
YearMonth stopYm = YearMonth.from( stopYear.atDay( 1 ) ) ;
定义我们找到的日期的集合。
int initialCapacity = ( int ) ChronoUnit.MONTHS.between( startYear.atDay( 1 ) , stopYear.atDay( 1 ) );
List< LocalDate > lastMondays = new ArrayList<>( initialCapacity ) ;
定义我们定位的星期几。使用DayOfWeek枚举。
DayOfWeek dow = DayOfWeek.MONDAY ;
使用TemporalAdjusters 类中的实现定义TemporalAdjuster。
TemporalAdjuster ta = TemporalAdjusters.lastInMonth( dow ) ;
循环月份。对于每个,确定第一个星期一。使用 TemporalAdjusters 类中的 TemporalAdjuster 实现。
YearMonth ym = startYm ;
while( ym.isBefore( stopYm ) ) {
LocalDate firstOfMonth = ym.atDay( 1 ) ;
LocalDate ld = firstOfMonth.with( ta ) ;
lastMondays.add( ld ) ; // Collect our last-monday-of-this-month.
// Set up the next loop.
ym = ym.plusMonths( 1 ) ;
}
报告。
System.out.println( lastMondays ) ;
看到code run live at IdeOne.com。
[2016-01-25, 2016-02-29, 2016-03-28, 2016-04-25, 2016-05-30, 2016-06-27, 2016-07-25, 2016-08- 29、2016-09-26、2016-10-31、2016-11-28、2016-12-26、2017-01-30、2017-02-27、2017-03-27、2017-04-24、 2017-05-29、2017-06-26、2017-07-31、2017-08-28、2017-09-25、2017-10-30、2017-11-27、2017-12-25]
现在让我们修改该循环以仅关注每月最后一天恰好是星期一的情况。
YearMonth ym = startYm;
while ( ym.isBefore( stopYm ) ) {
LocalDate endOfMonth = ym.atEndOfMonth();
if ( endOfMonth.getDayOfWeek().equals( dow ) ) {
lastMondays.add( endOfMonth ); // Collect our last-monday-of-this-month.
}
// Set up the next loop.
ym = ym.plusMonths( 1 );
}
看到这个code run live at IdeOne.com。
[2016-02-29, 2016-10-31, 2017-07-31]
请注意,这些结果与问题中给出的结果不同。我验证了这里的这些是正确的,并且问题的结果是不正确的。
关于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 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。