3 回答
TA贡献1852条经验 获得超7个赞
问题在于您的模式正在将整个字符串视为年份。您可以将.appendValue(ChronoField.YEAR, 4)其限制为四个字符:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendPattern("[-]MM[-]dd['T']HH[:]mm[:]ss[,S][.S]X")
.toFormatter();
这可以正确解析您的两个示例。
如果您想变得更加冗长,则可以执行以下操作:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.optionalStart().appendLiteral('-').optionalEnd()
.appendPattern("MM")
.optionalStart().appendLiteral('-').optionalEnd()
.appendPattern("dd")
.optionalStart().appendLiteral('T').optionalEnd()
.appendPattern("HH")
.optionalStart().appendLiteral(':').optionalEnd()
.appendPattern("mm")
.optionalStart().appendLiteral(':').optionalEnd()
.appendPattern("ss")
.optionalStart().appendPattern("X").optionalEnd()
.toFormatter();
TA贡献1815条经验 获得超10个赞
从文档中尚不清楚,但是我的猜测是发生了以下情况。
当您uuuuMMddHHmmss
在格式模式字符串中使用时,格式化程序可以轻松地看到有几个相邻的数字字段,因此可以使用字段宽度来分隔字段。前4位数字表示年份,依此类推。
相反,使用时uuuu[-]MM[-]dd['T']HH[:]mm[:]ss
,格式化程序不会将其视为相邻的数字字段。我同意彼得·劳瑞(Peter Lawrey)的评论,因此,它需要较长的数字来表示年份,最终超过最大年份(999999999),并引发异常。
TA贡献1799条经验 获得超9个赞
基于模式的DateTimeFormatter不够智能,无法同时处理可选部分和具有两个不分隔的数字字段的可能性。当确实需要数字字段不带分隔符时,不问任何问题,则模式会理解,模式字母从u更改为M意味着它需要对数字进行计数才能知道哪个数字是哪个字段的一部分。但是,如果这不是确定性的,那么模式就不会尝试这种方式。它看到一个完整描述的数字字段,而不是紧随其后的是另一个数字字段。因此,没有理由计算数字。所有数字都是应该在此处表示的字段的一部分。
为此,您不应该尝试使用模式来构建DateTimeFormatter,而应该使用Builder。从DateTimeFormatter.BASIC_ISO_DATE
附近以及其他人那里获取灵感。
添加回答
举报