JSR-310中两个不同的基于周的年度定义的动机是什么? [英] What is the motivation for two different week-based-year definitions in JSR-310?

查看:191
本文介绍了JSR-310中两个不同的基于周的年度定义的动机是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些是包中的两个字段 java.time.temporal

These are the two fields in the package java.time.temporal:

IsoFields.WEEK_BASED_YEAR

WeekFields.ISO.weekBasedYear()

ISO-8601定义了除其他两种日期之外的所谓周日期,即通常的日历日期(包括年,月和日) -month)和序数日期(由年和年组成)。 以YYYY-'W'ww-e 格式定义周日。 w代表一周的年份,e代表数字ISO-星期几。 Y代表以周为基础的年份,与日历年相同,但在日历年的开始或结束时除外,因为基于周的年份与最终可能在上一年开始的周周期相关联。有两条规则对于理解周日的形成非常重要:

ISO-8601 defines a so-called week date besides the other two kinds of date, namely the usual calendar date (consisting of year, month and day-of-month) and the ordinal date (consisting of year and day-of-year). A weekdate is defined in the format YYYY-'W'ww-e. w stands for the week-of-year, e for the numerical ISO-day-of-week. Y stands for the week-based-year and is identical to calendar year with the exception at the begin or end of calendar year, because a week-based-year is bound to the week cycle which can eventually start in the previous year. Two rules are important to understand how a week date is formed:


  1. 周总是从周一开始。

  2. 一个日历年的第一周是包含至少四天的一周。

乍一看JSR-310-字段似乎是相同的,因为ISO-8601仅提到一种基于周的年份。但是,等一下,惊喜。让我们考虑以下代码示例:

At first glance both JSR-310-fields appear to be identical because ISO-8601 only mentions one kind of week-based-year. But wait, surprise. Let's consider following code example:

LocalDate date1 = 
  LocalDate.of(2000, 2, 29).with(IsoFields.WEEK_BASED_YEAR, 2014);
System.out.println("IsoFields-Test: " + date1); // output: 2014-03-01

LocalDate date2 = 
  LocalDate.of(2000, 2, 29).with(WeekFields.ISO.weekBasedYear(), 2014);
System.out.println("WeekFields-Test: " + date2); // output: 2014-02-25

虽然我很清楚第二种变化我真的很惊讶查看第一个日期的不同结果,即在其类名中使用官方ISO-8601-reference。解释计算结果:

While I very well understand the second variation I am really astonished to see the different result for first date which is using the "official" ISO-8601-reference in its classname. To explain the calculated results:

日期2000-02-29对应于ISO-weekdate-notation的2000-W09-2,而2014-02-25对应于2014 -W09-2 保留一周中的星期和星期几。到目前为止很好。较小字段的这种保留特性类似于如何更改日历年的规则(在大多数情况下应该保持日历日期中的月份和日期不变)。

The date 2000-02-29 corresponds to 2000-W09-2 in ISO-weekdate-notation while 2014-02-25 corresponds to 2014-W09-2 preserving the week-of-year and the day-of-week. So far so fine. This preserving characteristics for smaller fields is similar to the rule how to change the calendar year (which should in most cases keep the month and day-of-month in a calendar date unchanged).

但结果2014-03-01是什么?这里算法简单地将相应的周日添加了四天,以便考虑日期字段(29对25)的差异。我没有找到任何关于此行为的来源或官方文档。有谁知道我们在哪里可以找到这两个领域之间差异的理由?有关算法行为的任何文档吗?

But what is about the result 2014-03-01? Here the algorithm has simply added four days to the corresponding week-date in order to take in account the difference in the field "day-of-month" (29 versus 25). I have not found any source or official documentation for this behaviour. Does anybody know where we can find the justification for the difference between these two fields? Any documentation available about the algorithmic behaviour?

更新:

现在我试过使用此表达式测试新API的自我一致性,以便找出更好支持哪两个字段:

Now I tried to test the self-consistency of the new API with this expression in order to find out which of the two fields is better supported:

System.out.println(
  "14 week-based-years later = "
  + LocalDate.of(2000, 2, 29).plus(14, IsoFields.WEEK_BASED_YEARS));

输出为2014-03-01,类似于描述的 IsoFields的情况.WEEK_BASED_YEAR ,虽然我仍然觉得结果更合理2014-02-25(= 2014-W09-2)。由于此类时间单位也在类 IsoFields 中找到,因此行为在类 IsoFields 中是自洽的。看起来像一个没有文档记录和非直观的功能。

The output is 2014-03-01 similar to the described case of IsoFields.WEEK_BASED_YEAR, although I still find the result 2014-02-25 (=2014-W09-2) much more logical. Since this temporal unit is also found in the class IsoFields so far the behaviour is self-consistent within the class IsoFields. Looks like an undocumented and non-intuitive "feature".

我使用的版本: java.runtime.version = 1.8.0-b132

更多测试:

LocalDate d = LocalDate.of(2014, 3, 1); // 2014-W09-6
System.out.println(
  "week-of-year in 2014-03-01: " 
  + d.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
System.out.println(
  "day-of-week in 2014-03-01: " 
  + d.get(ChronoField.DAY_OF_WEEK));

LocalDate later = d.plus(14, IsoFields.WEEK_BASED_YEARS); // 2028-03-02 = 2028-W09-4
System.out.println(
  "14 week-based-years later = " 
  + later);
System.out.println(
  "week-of-year in " + later + ": " 
  + later.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
System.out.println(
  "day-of-week in " + later + ": " 
  + later.get(ChronoField.DAY_OF_WEEK));

输出:

week-of-year in 2014-03-01: 9
day-of-week in 2014-03-01: 6
14 week-based-years later = 2028-03-02
week-of-year in 2028-03-02: 9
day-of-week in 2028-03-02: 4

我不承认任何明确的规则。在添加14周的年份时,不保留星期几,也不保留日期。 所以这是一个额外的问题:背后的规则是什么?IsoFields.WEEK_BASED_YEARS 也许JSR-310团队可以启发我们?

I do not recognize any clear rule. Neither the day-of-week is preserved nor the day-of-month is preserved while adding 14 week-based-years. So this is an extra question: What is the rule behind IsoFields.WEEK_BASED_YEARS? Maybe JSR-310-team can enlighten us?

推荐答案

这是 IsoFields 中的一个错误,因为此方法未经测试(对于那个很抱歉)。正确实施时, IsoFields WeekFields.ISO 之间应该有非常小的可观察差异。

This is a bug in IsoFields which managed to slip through because this method was untested (sorry about that). There should be very little observable difference between IsoFields and WeekFields.ISO when implemented correctly.

请参阅最终的错误报告和补丁通过系统工作并修复。

See the bug report and patch which will eventually work through the system and be fixed.

注意,测试显示获得该字段没问题,该bug只影响了 / adjustInto WEEK_BASED_YEAR 的方法。单位 WEEK_BASED_YEARS 受到影响,因为通过重复使用损坏的 WEEK_BASED_YEAR 来内部实施添加。

Note, testing revealed that getting the field is fine, the bug only affected the with/adjustInto method of WEEK_BASED_YEAR. The unit WEEK_BASED_YEARS is affected because the addition is implemented internally by reusing the broken WEEK_BASED_YEAR.

更新2014-08-28:这是14个java.time错误之一已在8u20修复

Update 2014-08-28: This was one of 14 java.time bugs fixed in 8u20.

这篇关于JSR-310中两个不同的基于周的年度定义的动机是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆