Java 8 DateTimeFormatter 解析可选部分

标签 java java-8 java-time date-parsing

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

  • 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/

相关文章:

Java fx 打印文本

java - 如何使用流来计算接收输入的数组的总和?

spring - 无法将 'java.lang.String' 类型的属性值转换为 thymeleaf 形式的属性 'java.time.LocalDate' 所需的类型 'date'

java - 如何将时间戳字符串转换为纪元时间?

java - 如何将日期截断/跨度为一个时间间隔?

java - Java中的类和对象问题

java - 如何在java中打印一个静态方法,该方法接受一个int作为参数并返回一个double

java - 其他类中的 JButton 操作

java - 处理 Lambda 表达式中的异常

java - Java8 中将 arraylist 嵌套到 hashmap