在 JSR-310 中,基于周的两个不同年份定义的动机是什么?
以下是包中的两个字段:java.time.temporal
WeekFields.ISO.weekBasedYear()
ISO-8601定义了除其他两种日期之外的所谓星期日期,即通常的日历日期(由年,月和月日组成)和序号日期(由年和年日组成)。星期日期以 YYYY-'W'ww-e 格式定义。w 代表一年中的一周,e 代表数字 ISO 星期几。Y 代表基于周的年份,与日历年相同,但在日历年的开始或结束时除外,因为基于周的年份绑定到最终可能从前一年开始的周周期。有两条规则对于了解周日期的形成方式非常重要:
- 周总是从星期一开始。
- 日历年的第一周是包含至少四天的一周。
乍一看,这两个 JSR-310 字段似乎完全相同,因为 ISO-8601 只提到了一种基于周的年份。但是等等,惊喜。让我们考虑以下代码示例:
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参考。要解释计算结果:
日期 2000-02-29 对应于 ISO-weekdate-表示法中的 2000-W09-2,而 2014-02-25 对应于 2014-W09-2,保留一周和星期几。到目前为止,一切都很好。较小字段的这种保留特征类似于如何更改日历年的规则(在大多数情况下,日历日期中的月份和月份日期应保持不变)。
但是结果如何 2014-03-01?在这里,该算法只是在相应的星期日期中添加了四天,以便考虑“月中的某一天”字段的差异(29对25)。我没有找到任何关于这种行为的来源或官方文件。有谁知道我们在哪里可以找到这两个领域之间差异的理由?有关算法行为的任何可用文档?
更新:
现在,我尝试使用此表达式测试新 API 的自一致性,以便找出两个字段中的哪个字段受更好支持:
System.out.println(
"14 week-based-years later = "
+ LocalDate.of(2000, 2, 29).plus(14, IsoFields.WEEK_BASED_YEARS));
输出是 2014-03-01 类似于所描述的情况,尽管我仍然发现结果 2014-02-25 (=2014-W09-2) 更合乎逻辑。由于到目前为止,这个时间单位在类中也被发现,因此该行为在类中是自洽的。看起来像一个未记录且非直观的“功能”。IsoFields.WEEK_BASED_YEAR
IsoFields
IsoFields
我使用的是版本: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团队可以启发我们?