3

我有一个 Java 日期:tempDate = Sun Jan 01 00:00:00 GMT+01:00 2012。

我想创建一个新的日期,即 tempDate 年第一周的第一天。

那是:

  Mon Jan 02 00:00:00 GMT+01:00 2012

当我尝试使用 Joda Time 时:

DateTime cal = new DateTime(tempDate).withWeekOfWeekyear(1).
                     withDayOfWeek(DateTimeConstants.MONDAY);

我得到了我想要的,但在前一年:

Mon Jan 03 00:00:00 GMT+01:00 2011

如何在 Joda Time 中完成这项工作?

4

2 回答 2

8

您必须了解 DateTime 的年份和它的周年份之间的区别。

Joda-Time中,根据ISO 8601 标准,星期一是一周的第一天。然而,岁月并不总是从星期一开始。根据 ISO 标准,一年的第一周是包含该年第一个星期四的那一周。因此,一年中的某些日子可能会落入上一年或下一年的一周。

在您的示例中,2012 年 1 月 1 日实际上是这样的一天。它属于 2011 年的第 52 周。所以它的年份(2012 年)不同于它的周年(2011 年)。因此,如果您将日期更改为其一周年的第一周,您将获得2011 年第一周的DateTime

为了使这项工作始终如一,您只需确保您的一周年份与您的年份相同:

DateTime onTheFirstDayOfTheFirstWeek = dateTime.withWeekyear(dateTime.getYear()).withWeekOfWeekyear(1).withDayOfWeek(1);

顺便说一句,您评论中的解决方法将无法始终如一地工作,特别是当系统时间落在与一周年份不同的年份时,它将失败。

于 2013-02-18T14:11:03.133 回答
2

鲍莫尔的答案是正确的,回答了这个问题。

如果您确实想遵循ISO 8601标准定义的一周第一周,这里有一些使用Joda-Time 2.3 的示例代码。

请注意withTimeAtStartOfDay获取当天第一刻的调用。日子并不总是从00:00:00时间开始。

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );

DateTime now = new DateTime( timeZone );
DateTime firstWeekStart = now.withWeekOfWeekyear(1).withDayOfWeek( DateTimeConstants.MONDAY ).withTimeAtStartOfDay();
DateTime firstWeekStop = firstWeekStart.plusWeeks( 1 );
Interval firstWeek = new Interval( firstWeekStart, firstWeekStop );

转储到控制台...</p>

System.out.println( "now: " + now );
System.out.println( "firstWeekStart: " + firstWeekStart );
System.out.println( "firstWeekStop: " + firstWeekStop );
System.out.println( "firstWeek: " + firstWeek );
firstWeek: 2013-12-30T00:00:00.000+01:00/2014-01-06T00:00:00.000+01:00

运行时……</p>

now: 2014-02-07T12:49:33.623+01:00
firstWeekStart: 2013-12-30T00:00:00.000+01:00
firstWeekStop: 2014-01-06T00:00:00.000+01:00
于 2014-02-07T11:54:57.920 回答