我需要将日期时间解析为以两种不同格式出现的字符串:
- 19861221235959Z
- 1986-12-21T23:59:59Z
下面的 dateTimeFormatter 模式正确地解析了第一种日期字符串
DateTimeFormatter.ofPattern ("uuuuMMddHHmmss[,S][.S]X")
但在第二个上失败,因为不需要破折号、冒号和 T。
我的尝试是使用如下可选部分:
DateTimeFormatter.ofPattern ("uuuu[-]MM[-]dd['T']HH[:]mm[:]ss[,S][.S]X")
出乎意料的是,这会解析第二种日期字符串(带破折号的),但不会解析第一种,抛出一个
java.time.format.DateTimeParseException: Text '19861221235959Z' could not be parsed at index 0
好像可选部分没有被评估为可选......
最佳答案
问题是您的模式将整个字符串视为年份。您可以使用 .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();
关于Java 8 DateTimeFormatter 解析可选部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51176936/