使用 DateTimeFormatter 解析 Java Time 的基于周的年模式

标签 java java-8 java-time iso8601

我需要以 week-based-year-week-of-week-based-year 格式输出当前日期,即使用 ISO week date其中一周总是从星期一开始,一年中的第一周是一月份至少有四天的第一周(因此在一月份有第一个星期四的那一周)。

由于2015年12月31日是周四,周五到周日,即2016年1月1日到3日,都属于2015年的第53周(“长年”),而2016年的第一周从周一开始, 1 月 4 日。

来自DateTimeFormatter spec ,我原以为我可以只使用模式 YYYY-ww 来做到这一点(Yweek-based-yearwweek-of-week-based-year).

但是,当我尝试类似以下简化的测试用例时:

String dateString = "2016-01-03";
LocalDate date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String expectedOutput = "2015-53";
String actualOutput = date.format(DateTimeFormatter.ofPattern("YYYY-ww"));
System.out.println("Parsing " + dateString + ", expected "
        + expectedOutput + " but got " + actualOutput);
System.out.println(dateString + " as ISO week date: "
        + date.format(DateTimeFormatter.ISO_WEEK_DATE));

我明白了:

Parsing 2016-01-03, expected 2015-53 but got 2016-02

2016-01-03 as ISO week date: 2015-W53-7

所以使用内置的 ISO_WEEK_DATE 格式化程序可以达到我的预期,但是使用模式 YYYY-ww 似乎给了我日历年和周。

我是不是对 ISO 周日期有什么误解,或者我的代码中有错误,或者...我敢说...这是 java.time 库中的错误吗(与 this question 的情况一样)?

我知道我可以使用如下所示的自定义格式化程序来解决这个问题,但就我而言,我确实需要它来使用模式。

new DateTimeFormatterBuilder()
    .parseCaseInsensitive()
    .appendValue(IsoFields.WEEK_BASED_YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
    .appendLiteral("-")
    .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
    .toFormatter();

最佳答案

DateTimeFormatterBuilder 的文档指定“Y”附加本地化的基于周的年份。因此,基于周的年份和周字段的含义将取决于格式化程序中设置的语言环境。

关于使用 DateTimeFormatter 解析 Java Time 的基于周的年模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39584350/

相关文章:

java - PKCS11Exception ckr_attribute_type_invalid

java - 如何在 WildFly 上升级 Artemis

java - 如何在 Java 8 中解析 LDAP 通用时间?

date - 获取午夜和当前时间JDK 8之间的时间范围

java - 带有 Java 8 时钟的 JUnit

java - 在 Ubuntu 中为 java 安装公共(public)数学库

java - 如何正确更新 JLabel 中的图像?

java - Stream.sorted().limit() 的性能

java - 使用Java 8 Streams完成消除循环

java - thenAccept 和 thenApply 的区别