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

时间:2012-09-30 12:19:43

标签: java date datetime calendar

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

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

由于

4 个答案:

答案 0 :(得分:12)

TL;博士

  

获取上周一和周五的日期

LocalDate previousMonday = 
    LocalDate.now( ZoneId.of( "America/Montreal" ) )
             .with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) ) ;

避免遗留日期时间类

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

LocalDate

LocalDate类表示没有时间且没有时区的仅限日期的值。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。

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实施:previousOrSamenextOrSame

关于 java.time

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

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

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

从哪里获取java.time类?

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

答案 1 :(得分:9)

注意:对于Java 8及更高版本,请查看Basil Bourque的答案(link)。
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);

您可以从DateTime个对象创建java.util.Date个对象,反之亦然,因此可以很容易地使用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”。

答案 2 :(得分:3)

你仍然将星期开始设置为星期日,这意味着星期六的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转换等麻烦。

答案 3 :(得分:1)

我唯一看错的是你实际上正在测试范围 Mo-Fr,而不是如上所述检索两个特定日期。以独占上限测试范围Mo-Sa会更安全。