Java 8 在DateTimeFormatter中处理多种格式

Java 8 在DateTimeFormatter中处理多种格式,java-8,date-formatting,dateformatter,Java 8,Date Formatting,Dateformatter,我正在使用Java 8开发一个函数,该函数必须处理以下日期从String到LocalDateTime的转换: 2019-06-20 12:18:07.207+0000 UTC 2019-06-20 12:18:07.20+0000 UTC 2019-06-20 12:18:07.2+0000 UTC 2019-06-20 12:18:07+0000 UTC 这些字符串是从我无法更改的外部库生成的 按照SO答案中给出的建议,我尝试使用类型DateTimeFormatter提供的可选格式,使用字

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

  • 2019-06-20 12:18:07.207+0000 UTC
  • 2019-06-20 12:18:07.20+0000 UTC
  • 2019-06-20 12:18:07.2+0000 UTC
  • 2019-06-20 12:18:07+0000 UTC
这些字符串是从我无法更改的外部库生成的

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

  • yyyy-MM-dd HH:MM:ss[.S[S]]Z Z
  • yyyy-MM-dd HH:MM:ss[.S[S]]Z Z
然而,两者都不起作用


有什么建议吗?

我认为最好使用
DateTimeFormatterBuilder
来实现这一目的。对于可选零件,只需使用以下方法之一:

  • &
  • 将整个可选模式附加到
  • 以下是一个例子:

    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]"
    );
    
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendValue(HOUR_OF_DAY,2)
        .optionalStart()
        .appendValue(MINUTE_OF_HOUR,2)
        .optionalEnd()
        .optionalStart()
        .appendValue(SECOND_OF_MINUTE,2)
        .optionalEnd();
        .toFormatter();
    
    此外,您还可以为每个可选项创建dtf,并使用appendOptional()和
    DateTimeFormatterBuilder

    例如:

    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]"
    );
    
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendValue(HOUR_OF_DAY,2)
        .optionalStart()
        .appendValue(MINUTE_OF_HOUR,2)
        .optionalEnd()
        .optionalStart()
        .appendValue(SECOND_OF_MINUTE,2)
        .optionalEnd();
        .toFormatter();
    

    此代码未经测试,但每次尝试在开始/结束可选块中构建可选模式。

    您可以使用
    DateTimeFormatterBuilder
    构建模式,并重用
    ISO_LOCAL_DATE
    ISO_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
    处理用于表示毫秒的不同位数。从JavaDoc:

    这将返回一个不可变的格式化程序,该格式化程序能够格式化和解析ISO-8601扩展本地时间格式。格式包括:
    […]
    一到九个数字表示纳秒。将根据需要输出尽可能多的数字


    在答案的第一部分中,您引用了
    DateTimeFormatterBuilder
    ,但在示例中没有使用它。你能修改答案吗?我添加了一个简单的例子,说明它如何与构建器一起工作,我没有测试它。第一种方法有效吗?对不起,你的回答没有回答我的问题。可选和可变部分是毫秒块,而不是偏移量。ISO_LOCAL_TIME本身不负责毫秒的可选部分吗?试着用这段代码运行示例。是的,你是对的。很抱歉我在你的回答中添加了一些有用的信息。谢谢。你同意分区约会,对吗?我认为在问题中使用LocalDateTime的要求与需要解析的特定于区域的文本冲突。不要担心。问题在于可选部分。