检索上周一和上周五日期的最佳方法是什么tl;博士避免使用旧日期时间类LocalDateTemporalAdjuster关于 java.time

2022-09-03 16:52:38

我需要获取上周星期一和星期五的日期。为此,我得到本周星期一的日期并减去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);

以上是有效的,但我感兴趣的是逻辑是否有任何错误。即,它是否适用于二月,闰年等。

请随时提出更好的解决方案/方法。

谢谢


答案 1

tl;博士

获取上周星期一和星期五的日期

LocalDate                                           // Represent a date only, without a time-of-day, and without a time zone or offset.
.now                                                // Capture the current date as seen through the wall-clock time used by the people of a certain region (a time zone). 
( 
    ZoneId.of( "America/Montreal" ) 
)                                                   // Returns a `LocalDate` object.
.with                                               // Move to another date.
( 
    TemporalAdjusters.previous( DayOfWeek.MONDAY )  // Returns an implementation of the `TemporalAdjuster` interface.
)                                                   // Returns another `LocalDate` object, separate and distinct from our original `LocalDate` object. Per the immutable objects design pattern. 

避免使用旧日期时间类

其他答案使用麻烦的旧旧日期时间类,现在被java.time问题所取代。

LocalDate

LocalDate 类表示一个仅日期值,不带时间,也不带时区。

时区对于确定日期至关重要。在任何给定的时刻,日期在全球范围内因区域而异。例如,法国巴黎午夜后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天”。

ZoneId z = ZoneId.of( “America/Montreal” );
LocalDate today = LocalDate.now( z );

TemporalAdjuster

临时调整接口提供从一个日期时间值移动到另一个日期时间值的调整。在 TemporalAdjusters 类中找到方便的实现(注意复数 “s”)。调整程序从星期几枚举中查找任何指定的对象。previous

这个问题没有确切地定义“上周”。最近七天?标准的周一至周日时段?本地化的周,例如美国的周日至周六?今天这一周之前的一周还是包括今天的部分星期?

我将假设前七天是有意的。

LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) ) ;
LocalDate previousFriday = today.with( TemporalAdjusters.previous( DayOfWeek.FRIDAY ) ) ;

顺便说一句,如果你想考虑初始日期,如果它恰好已经是所需的星期几,请使用替代实现:previousOrSamenextOrSameTemporalAdjuster


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


答案 2

注意:对于Java 8及更高版本,请查看Basil Bourque的答案(链接)。
Java 8引入了一个新的时间/日期API,它提供了Joda-Time的大部分功能。


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 日期一起使用。DateTimejava.util.Date


使用上述代码和日期

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”。