在 DateTimeFormatter 中处理多种格式

Handling multiple formats in DateTimeFormatter

我正在使用 Java 8 开发一个函数,该函数必须处理以下日期从 StringLocalDateTime 的转换:

这些字符串是从我无法更改的外部库生成的。

按照 SO 回答 Optional parts in SimpleDateFormat 中给出的建议,我尝试使用类型 DateTimeFormatter 提供的可选格式,使用字符 []。我尝试了以下模式:

然而,它们都不起作用。

有什么建议吗?

我认为为此目的使用 DateTimeFormatterBuilder 更好。对于可选部分,只需使用以下方法之一:

  1. OptionalStart() & OptionalEnd()
  2. appendOptional()
  3. 附加整个可选模式

这是一个例子:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(""
    + "[yyyy-MM-dd HH:mm:ss.SSS Z z]"
    + "[yyyy-MM-dd HH:mm:ss.SS Z z]"
    + "[yyyy-MM-dd HH:mm:ss.S Z z]"
    + "[yyyy-MM-dd HH:mm:ss Z z]"
);

此外,您可以为每个可选的创建一个 dtf 并附加它们 appendOptional() 和 DateTimeFormatterBuilder

例如:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendValue(HOUR_OF_DAY,2)
    .optionalStart()
    .appendValue(MINUTE_OF_HOUR,2)
    .optionalEnd()
    .optionalStart()
    .appendValue(SECOND_OF_MINUTE,2)
    .optionalEnd();
    .toFormatter();

此代码未经测试,但每次都尝试在 start/end 个可选块中构建您的可选模式。

您可以使用 DateTimeFormatterBuilder 构建模式并重复使用 ISO_LOCAL_DATEISO_LOCAL_TIME 常量:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(" ")
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendPattern("[ Z z]")
            .toFormatter();

    ZonedDateTime dt = ZonedDateTime.parse(date, formatter);

诀窍在于 DateTimeFormatter.ISO_LOCAL_TIME 处理用于表示毫秒数的不同位数。来自 DateTimeFormatter.ISO_LOCAL_TIME JavaDoc:

This returns an immutable formatter capable of formatting and parsing the ISO-8601 extended local time format. The format consists of:
[..]
One to nine digits for the nano-of-second. As many digits will be output as required.