检索上周一和周五的日期的最佳方法是什么
我需要得到上周一和周五的日期。 要做到这一点,我得到本周一的日期,减去7天。 这给了我上周一的星期一。
为了得到星期五的日期,我必须加上4.这让我感到困惑,因为出于某种原因,一周的第一天是星期日而不是星期一在英国。
无论如何,这是我如何得到日期。
// Get the dates for last MON & FRI Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); cal.add(Calendar.DAY_OF_WEEK, -7); cal.set(Calendar.HOUR_OF_DAY,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); cal.set(Calendar.MILLISECOND,0); // Get the date on Friday cal.add(Calendar.DAY_OF_WEEK, 4); cal.set(Calendar.HOUR_OF_DAY,23); cal.set(Calendar.MINUTE,59); cal.set(Calendar.SECOND,59); cal.set(Calendar.MILLISECOND,0);
上述工作,但我感兴趣的是逻辑有什么问题。 即它适用于Februarys,闰年等。
随意提出更好的解决方案/方法。
谢谢
注意:对于Java 8及以上版本,请查看Basil Bourque的答案( 链接 )。
Java 8引入了一个新的时间/日期API,它提供了Joda-Time的大部分function。
Joda-Time为这类问题提供了非常好的方法。
使用Joda Time获取上周一周五和周五的日期看起来像这样:
DateTime today = DateTime.now(); DateTime sameDayLastWeek = today.minusWeeks(1); DateTime mondayLastWeek = sameDayLastWeek.withDayOfWeek(DateTimeConstants.MONDAY); DateTime fridayLastWeek = sameDayLastWeek.withDayOfWeek(DateTimeConstants.FRIDAY);
您可以从java.util.Date
对象创建DateTime
对象,反之亦然,因此很容易使用Java日期。
使用上面的代码与日期
DateTime today = new DateTime("2012-09-30");
结果是星期一的“2012-09-17”和星期五的“2012-09-21”,将日期设置为
DateTime tomorrow = new DateTime("2012-10-01");
结果是星期一的“2012-09-24”和星期五的“2012-09-28”。
TL;博士
获取上周一和周五的日期
LocalDate previousMonday = LocalDate.now( ZoneId.of( "America/Montreal" ) ) .with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) ) ;
避免遗留日期时间类
其他Answers使用现在由java.time问题取代的麻烦的旧遗留日期时间类。
LocalDate
LocalDate
类表示没有时间且没有时区的仅日期值。
时区对于确定日期至关重要。 对于任何给定的时刻,日期在全球范围内因地区而异。 例如, 法国巴黎午夜过后几分钟,在魁北克蒙特利尔的 “昨天”仍然是新的一天。
ZoneId z = ZoneId.of( “America/Montreal” ); LocalDate today = LocalDate.now( z );
TemporalAdjuster
TemporalAdjuster
接口提供从一个日期时间值移动到另一个日期时间值的调整。 在TemporalAdjusters
类中找到方便的实现(注意复数的’s’)。 previous
调整器从DayOfWeek
枚举中查找任何指定的对象。
该问题没有完全定义“上周”。 过去七天? 标准周一至周日期间? 本地化周,如美国的周日至周六? 在今天的一周之前的一周或包括今天的部分周?
我将假设前七天是有意的。
LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) ) ; LocalDate previousFriday = today.with( TemporalAdjusters.previous( DayOfWeek.FRIDAY ) ) ;
顺便说一句,如果您想要考虑初始日期(如果它恰好已经是所需的星期几),请使用备用TemporalAdjuster
实现: previousOrSame
或nextOrSame
。
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.Date
, Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。
您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC驱动程序 。 不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
- Java SE 8 , Java SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和Java SE 7
- 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
- Android的
- 更高版本的Android捆绑java.time类的实现。
- 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如Interval
, YearWeek
, YearQuarter
等。
你仍然有星期一开始星期日,这意味着星期六的Calendar.MONDAY
是星期一,而星期日的Calendar.MONDAY
是第二天。
你需要做的是(根据你上面的评论你想要的方式),将星期开始设置为星期一。
Calendar cal = Calendar.getInstance(); cal.setFirstDayOfWeek(Calendar.MONDAY); cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); cal.add(Calendar.DAY_OF_WEEK, -7); ...
除此之外,并且星期五的最后一秒不包括在范围内,你的逻辑似乎是合理的,并且应该没有闰年/ DST转换等问题。
我唯一看错的是你实际上在测试范围 Mo-Fr,而不是如上所述,检索两个特定日期。 用独特的上限测试范围Mo-Sa会更安全。