Java 使用 DateTimeFormatter 解析时间的基于周的年模式
Java Time's week-of-week-based-year pattern parsing with DateTimeFormatter
我需要以 week-based-year
-week-of-week-based-year
格式输出当前日期,即使用 ISO week date,其中一周总是从星期一和一年的第一周开始是第一个在 1 月至少有 4 天的星期(因此是 1 月第一个星期四的那一周)。
由于2015年12月31日是周四,周五到周日,即2016年1月1日到3日,都属于2015年的第53周(“长年”),2016年的第一周从1 月 4 日星期一。
从 DateTimeFormatter spec 开始,我本以为我可以使用模式 YYYY-ww
来做到这一点(Y
是 week-based-year
和 w
是 week-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
似乎给了我 calendar 年和周.
我是不是对 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" 附加本地化的基于周的年份。因此,基于周的年和周字段的含义将取决于格式化程序中设置的语言环境。
我需要以 week-based-year
-week-of-week-based-year
格式输出当前日期,即使用 ISO week date,其中一周总是从星期一和一年的第一周开始是第一个在 1 月至少有 4 天的星期(因此是 1 月第一个星期四的那一周)。
由于2015年12月31日是周四,周五到周日,即2016年1月1日到3日,都属于2015年的第53周(“长年”),2016年的第一周从1 月 4 日星期一。
从 DateTimeFormatter spec 开始,我本以为我可以使用模式 YYYY-ww
来做到这一点(Y
是 week-based-year
和 w
是 week-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
似乎给了我 calendar 年和周.
我是不是对 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" 附加本地化的基于周的年份。因此,基于周的年和周字段的含义将取决于格式化程序中设置的语言环境。