繁体   English   中英

检索上周一和周五的日期的最佳方法是什么

[英]What is the best way to retrieve the dates for last Monday and Friday

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

以上有效,但我很感兴趣,如果逻辑有任何问题。 即它是否适用于二月、闰年等。

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

谢谢

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

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

该问题并未准确定义“上周”。 过去 7 天? 标准周一至周日? 本地化的一周,例如美国的周日至周六? 是今天周的前一周还是包括今天的部分周?

我假设前 7 天是有意的。

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

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


关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar ,和SimpleDateFormat

现在处于维护模式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 ,和更多

注意:对于 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.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”星期五。

您仍然将一周的开始设置为星期日,这意味着星期六的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); 
...

除此之外,周五的最后一秒不包括在范围内,您的逻辑似乎是合理的,并且应该不会遇到闰年/夏令时变化等问题。

我唯一认为错误的是您实际上是在测试范围Mo-Fr,而不是如上所述,检索两个特定的日期。 使用唯一的上限测试范围 Mo-Sa 会更安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM