更新:此处介绍的概念仍然适用,但代码已过时。 Joda-Time 项目现在位于 maintenance mode,建议迁移到 java.time 类。查看Answer by Szulc中的java.time代码。
简答
DateTime dateTimeStart = new DateTime( "2003-W01-1", DateTimeZone.UTC ); // Joda-Time 2.4.
DateTime dateTimeStop = dateTimeStart.plusWeeks( 1 );
有关详细信息,请继续阅读。
避免 j.u.Date
与 Java 捆绑在一起的旧 java.util.Date 和 java.util.Calendar 类是出了名的麻烦,应该避免使用。 Sun 及其合作伙伴在 Java 库中添加了很多简洁的东西,但并不是所有的东西都是好的。日期时间类可能是最糟糕的。
此外,这些类对ISO 8601 weeks 的支持较弱。详情请见this answer。
ISO 周规则
您可以使用这些类编写自己的代码,但我不建议这样做。 ISO周数的计算规则很简单:
- 第 1 周是日历年的第一个星期四。
- 星期一是一周的第一天。
乔达时间
取而代之的是一个名为Joda-Time 的库。该库包括对 ISO 周的出色支持。
添加到您的项目很简单,只需添加一个 .jar 文件。
其他示例代码
参见 other answer of mine 或 this one 示例代码,用于从 ISO 周数中获取日期时间。
java.time
Java 8 有一个新的日期时间框架,它受 Joda-Time 的启发,位于 java.time 包中。
添加库
Java 旨在将库混合在一起。这样做是面向对象编程和后期绑定的主要目的之一。您问题中的 cmets 指的是老板非理性或无知地禁止添加库的非常常见的情况。虽然这种禁令有正当理由,但很少见。
禁止在 Java 中添加库和 jar 就像禁止将拖车挂在配备挂钩的车队上。
旧的日期时间类确实很糟糕,以至于我们中的许多人将 Joda-Time 作为一种习惯添加到大多数新项目中。
半开
在日期时间工作中,定义时间跨度的常用方法是“半开放”方法。这意味着开始是包容的,而结束是排斥的。因此,标准周从星期一的第一刻开始,到下星期一的第一刻结束。搜索 StackOverflow.com 以获取更多讨论和示例。
ISO 周的文字表示
ISO 8601 标准定义了represent a standard week 甚至该周内的一天的方式。
以年份、连字符、W 分隔符和周数表示整周:YYYY-Www。添加连字符和星期几以查明该周内的某一天:YYYY-Www-D。
Joda-Time 理解这种格式,如下面的代码示例所示。
示例代码
这是一些 Joda-Time 2.4 代码。在 StackOverflow.com 上搜索这些概念的讨论和示例。这个问题和这个答案几乎重复了许多其他问题。
int year = 2003;
int week = 1; // Domain: 1 to 53.
// Build a String in ISO 8601 Week format: YYYY-Www-D
// Hard-coding a `1` for Monday, the standard first-day-of-week.
String input = ( String.format( "%04d", year ) + "-W" + String.format( "%02d", week ) + "-1" );
// Specify the time zone by which to define the beginning of a day.
DateTimeZone timeZone = DateTimeZone.UTC; // Or: DateTimeZone.forID( "America/Montreal" );
// Calculate beginning and ending, using Half-Open (inclusive, exclusive) approach.
DateTime dateTimeStart = new DateTime( input, timeZone );
DateTime dateTimeStop = dateTimeStart.plusWeeks( 1 );
// Use Joda-Time's tidy Interval class to represent the entire week. Use getters to access start and stop.
Interval weekInterval = new Interval( dateTimeStart, dateTimeStop );
// Is today in that week? Joda-Time has handy methods: contains, isBefore, isAfter, overlap.
boolean isTodayInThatWeek = weekInterval.contains( DateTime.now() );
转储到控制台。
System.out.println( "input: " + input );
System.out.println( "dateTimeStart: " + dateTimeStart );
System.out.println( "dateTimeStop: " + dateTimeStop );
System.out.println( "interval: " + interval );
System.out.println( "isTodayInThatWeek: " + isTodayInThatWeek );
运行时。
input: 2003-W01-1
dateTimeStart: 2002-12-30T00:00:00.000Z
dateTimeStop: 2003-01-06T00:00:00.000Z
interval: 2002-12-30T00:00:00.000Z/2003-01-06T00:00:00.000Z
isTodayInThatWeek: false