[英]Java Calendar WEEK_OF_YEAR not ISO-8601compliant?
The ISO-8601 standard states that ISO-8601标准规定了这一点
"The first week of a year is the week that contains the first Thursday of the year (and, hence, always contains 4 January)."
“一年的第一周是包含一年中第一个星期四的一周(因此,总是包含1月4日)。”
Meaning the first week of the year is not that which contains January the 1st but the first one that contains at leat four days into the new year. 这意味着一年中的第一周不是包含1月1日的那一周,而是包含在新年四天的第一个星期。
Acording to that Mon, January 11 2016 is on week #2. 根据周一,2016年1月11日是第2周。 Here is a list of week numbers for 2016.
以下是2016年的周数列表。
Ubuntu reflects that in its time widget: Ubuntu在其时间小部件中反映出:
And the cal command does also: 而且cal命令也有:
Oracle supports it with the "iw" parameter of TO_CHAR
: Oracle使用
TO_CHAR
的“iw”参数支持它:
> select to_char(to_date('11/01/2016','dd/mm/yyyy'),'iw') weekno from dual;
> WEEKNO
02
But Java says Mon, January 11 2016 is week #3 但Java表示2016年1月11日星期一是第3周
Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
System.out.println(c.get(Calendar.WEEK_OF_YEAR));
Output:
Mon Jan 11 09:02:35 VET 2016
3
Java thinks the first week of the year is the one that contains January the 1st. Java认为一年中的第一周是包含1月1日的那一周。
- Is there a way for Java to use the ISO-8601-copliant week numbering? - Java是否有办法使用符合ISO-8601标准的周编号?
As I noted in my comment, the default behavior is locale specific. 正如我在评论中指出的那样, 默认行为是特定于语言环境的。 Some locales will give 3, some will give 2.
一些语言环境会给出3,有些会给出2。
Luckily, you can specify the number of days that has to be present in the first week of the year, for a given Calendar
. 幸运的是,对于给定的
Calendar
,您可以指定一年中第一周必须出现的天数。 As you write above, for ISO 8601, this number is 4
, thus the following code should work: 如上所述,对于ISO 8601,此数字为
4
,因此以下代码应该有效:
Calendar c = Calendar.getInstance();
c.setMinimalDaysInFirstWeek(4); // For ISO 8601
System.out.println(c.getTime());
System.out.println(c.get(Calendar.WEEK_OF_YEAR));
This should make the output correct regardless of locale. 无论语言环境如何,这都应该使输出正确。
Test output: 测试输出:
Mon Jan 11 14:54:22 CET 2016
2
myZonedDateTime.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )
…and… …和…
myZonedDateTime.get( IsoFields.WEEK_BASED_YEAR )
As the correct Answer by haraldK explains, the Calendar
class's definition of week varies by locale . 正如haraldK的正确答案所解释的那样,
Calendar
类对周的定义因地区而异 。 While well-intentioned, this is confusing. 善意的,这是令人困惑的。
You should be avoiding Calendar
and related classes such as Date
. 您应该避免使用
Calendar
和相关类,例如Date
。 They are now supplanted by the java.time classes. 它们现在被java.time类取代。
As for ISO 8601 week , be clear that means: 至于ISO 8601周 ,明确表示:
The java.time classes include limited support for ISO 8601 standard weeks . java.time类包括对ISO 8601标准周的有限支持。 Call the
get
method on various classes such as LocalDate
and ZonedDateTime
. 在各种类(如
LocalDate
和ZonedDateTime
上调用get
方法。 Pass the TemporalField
implementations found as constants in the IsoFields
class. 传递在
IsoFields
类中作为常量找到的TemporalField
实现。
int week = myZonedDateTime.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int weekBasedYear = myZonedDateTime.get( IsoFields.WEEK_BASED_YEAR ) ;
Even better, add the ThreeTen-Extra library to your project to use YearWeek
class. 更好的是,将ThreeTen-Extra库添加到项目中以使用
YearWeek
类。
org.threeten.extra.YearWeek yw = YearWeek.from( myZonedDateTime ) ;
Never assume the definition of a week number. 永远不要假设周数的定义。 Be sure the source of such a number has the same definition of week as you, such as ISO 8601 definition.
确保此类数字的来源与您的周定义相同,例如ISO 8601定义。
For example, the Calendar app supplied by Apple with macOS defaults to a "Gregorian" calendar definition of week. 例如, Apple提供的macOS 日历应用程序默认为星期的“格里高利”日历定义。 As for what that means, I do not know as I could not find any documentation about their intent/definition.
至于那意味着什么,我不知道,因为我找不到任何关于他们的意图/定义的文件。 For ISO 8601 weeks, you must change a setting away from default .
对于ISO 8601周,您必须更改默认设置 。
The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as
java.util.Date
, Calendar
, & SimpleDateFormat
. 这些类取代了麻烦的旧遗留日期时间类,如
java.util.Date
, Calendar
和SimpleDateFormat
。
The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 。 And search Stack Overflow for many examples and explanations.
并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 .
规范是JSR 310 。
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. 使用符合JDBC 4.2或更高版本的JDBC驱动程序 ,您可以直接与数据库交换java.time对象。 No need for strings nor java.sql.* classes.
不需要字符串也不需要java.sql。*类。
Where to obtain the java.time classes? 从哪里获取java.time类?
The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time.
该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as
Interval
, YearWeek
, YearQuarter
, and more . 您可以在这里找到一些有用的类,比如
Interval
, YearWeek
, YearQuarter
,和更多 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.