gpt4 book ai didi

java - 无法从基于周的字符串的 TemporalAccessor 获取 LocalDate

转载 作者:搜寻专家 更新时间:2023-11-01 02:35:16 26 4
gpt4 key购买 nike

我正在尝试将格式为“YYYYww”(例如 201901)的简单字符串解析为 LocalDate,但我的尝试都没有成功。

我试图通过简单地使用模式“YYYYww”以及通过手动将值附加到 FormatterBuilder 来解析它。由于我的输入字符串不包含一天,我还将格式化程序配置为默认为星期日。

以下是运行 Java 8 (IBM JRE 8.0.5.25) 时对我来说失败的代码。

public static void main(String[] args) {
formatter1(); // Unable to obtain LocalDate from TemporalAccessor
formatter2(); // Text '201901' could not be parsed at index 0
formatter3(); // Text '201901' could not be parsed at index 6
}

public static void formatter1() {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(WeekFields.ISO.weekBasedYear(), 4, 4, SignStyle.NEVER)
.appendValue(WeekFields.ISO.weekOfYear(), 2, 2, SignStyle.NEVER)
.parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())
.toFormatter();

LocalDate.parse("201901", formatter);
}

public static void formatter2() {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("YYYYww")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())
.toFormatter();

LocalDate.parse("201901", formatter);
}

public static void formatter3() {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseLenient()
.appendPattern("YYYYww")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())
.toFormatter();

LocalDate.parse("201901", formatter);
}

如示例代码所示,我收到不同的错误消息,尤其是第一个示例让我感到困惑,因为 TemporalAccessor 包含基于周的年份、一年中的星期和工作日,这应该足以构造一个 LocalDate。

Exception in thread "main" java.time.format.DateTimeParseException: Text '201901' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {WeekOfYear[WeekFields[MONDAY,4]]=1, WeekBasedYear[WeekFields[MONDAY,4]]=2019, DayOfWeek=7},ISO of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1931)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1866)
at java.time.LocalDate.parse(LocalDate.java:411)
at Main.formatter1(Main.java:22)
at Main.main(Main.java:10)
Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {WeekOfYear[WeekFields[MONDAY,4]]=1, WeekBasedYear[WeekFields[MONDAY,4]]=2019, DayOfWeek=7},ISO of type java.time.format.Parsed
at java.time.LocalDate.from(LocalDate.java:379)
at java.time.LocalDate$$Lambda$7.000000001061ED20.queryFrom(Unknown Source)
at java.time.format.Parsed.query(Parsed.java:237)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1862)
... 3 more

最佳答案

这适用于 Java 8 及更高版本:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(WeekFields.ISO.weekBasedYear(), 4)
.appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2)
.parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())
.toFormatter();

System.out.println(LocalDate.parse("201901", formatter));

输出是:

2019-01-06

我已经在 Oracle Java 1.8.0_101 上进行了测试。我没有安装任何 IBM Java。

让它工作的关键是使用 weekOfWeekBasedYear() 而不是 weekOfYear()。我的其他变化是装饰性的。 WeekFields.ISO.weekOfYear() 通过计算一年中的星期一来定义周数,这不是您想要的,因为根据 ISO,第 1 周可能从上一年年底附近的星期一开始( 12 月 29 日至 31 日)。因此,它也不能很好地用于基于周的年份,并且 Java 拒绝将两者一起使用来标识一周。

在 Java 9 上,您的 formatter2()formatter3() 也可以工作(在 Oracle Java 9.0.4 上测试)。 Java 8 中似乎存在一个错误,即相邻字段解析对 YYYYww 不起作用。不过,我搜索了 Oracle Java 错误数据库,但没有找到错误描述。

ISO 8601

ISO 8601 是规定您正在使用的星期定义的标准,它还定义了星期的格式。它就像 2012-W48。因此,除非您有充分且非常具体的理由不这样做,否则这是您应该使用的格式,尤其是在与任何外部系统交换数据时。它还恰好消除了 Java 8 上的相邻字段解析问题。

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("YYYY-'W'ww")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())
.toFormatter();

System.out.println(LocalDate.parse("2019-W01", formatter));

2019-01-06

链接

关于java - 无法从基于周的字符串的 TemporalAccessor 获取 LocalDate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57479061/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com