Java 8 DateTimeFormatter解析可选部分

Cec*_*Cec 5 java date-parsing java-8 java-time

我需要将日期时间解析为两种不同格式的字符串:

  • 19861221235959Z
  • 1986-12-21T23:59:59Z

以下dateTimematmat模式正确解析第一种日期字符串

DateTimeFormatter.ofPattern ("uuuuMMddHHmmss[,S][.S]X")
Run Code Online (Sandbox Code Playgroud)

但是第二个失败,因为没有预期破折号,冒号和T.

我的尝试是使用如下可选部分:

DateTimeFormatter.ofPattern ("uuuu[-]MM[-]dd['T']HH[:]mm[:]ss[,S][.S]X")
Run Code Online (Sandbox Code Playgroud)

出乎意料的是,这解析了第二种日期字符串(带有破折号的日期字符串),但不是第一种,抛出一个

java.time.format.DateTimeParseException: Text '19861221235959Z' could not be parsed at index 0
Run Code Online (Sandbox Code Playgroud)

就像可选部分没有被评估为可选部分一样......

Mic*_*ael 9

正如彼得在评论中所说,问题是你的模式正在考虑整个字符串作为年份.您可以使用.appendValue(ChronoField.YEAR, 4)它将其限制为四个字符:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendValue(ChronoField.YEAR, 4)
    .appendPattern("[-]MM[-]dd['T']HH[:]mm[:]ss[,S][.S]X")
    .toFormatter();
Run Code Online (Sandbox Code Playgroud)

这可以用你的两个例子正确解析.

如果你想要更加冗长,你可以这样做:

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();
Run Code Online (Sandbox Code Playgroud)

  • 有用.布拉沃.但是,您应该使用"X"来解析问题中的偏移量. (3认同)