解析日期的格式可能不同

时间:2018-07-31 09:09:19

标签: java datetime java-8 java.time.instant

我必须将String解析为UTC的时间戳。 String可以具有以下格式:

  • YYYY-MM-DDThh:mm:ss.sssZ
  • YYYY-MM-DDThh:mm:ss.sss+/-hh:mm
  • YYYY-MM-DDThh:mm:ss.sss(考虑到UTC,因此请在末尾添加Z

避免这种情况的最佳方法是什么?

    try {
        firstDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
    } catch (DateTimeParseException e) {
        try {
            secondDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
        } catch (DateTimeParseException e2) {
                thirdDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
        }
    }

1 个答案:

答案 0 :(得分:1)

有多种选择。这是一个简单的例子:

private static DateTimeFormatter formatter 
        = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS[XXX]")
                .withZone(ZoneOffset.UTC);

public static Instant parse(String offsetDateTimeString) {
    return OffsetDateTime.parse(offsetDateTimeString, formatter).toInstant();
}

让我们尝试一下:

    System.out.println(parse("2018-08-04T21:41:55.987Z"));
    System.out.println(parse("2018-08-04T19:41:55.987-02:00"));
    System.out.println(parse("2018-08-04T21:41:55.987"));

此打印:

2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z

格式模式字符串中的方括号包围可选部分,因此可能存在偏移或没有偏移。偏移X使用Z表示零偏移,因此与三种格式中的前两种匹配。要指定字符串中没有偏移量时要使用的偏移量,我在格式化程序上设置了UTC的默认时区。

变化包括:

  • 您可以使用预定义的ISO格式,而不用自己编写整个格式模式字符串。
  • 由于我们使用的是偏移量而不是时区,因此指定默认偏移量而不是默认时区可能更正确。

DateTimeFormatterBuilder允许我们同时做。因此,您可以在上面的代码中使用另一种格式化程序:

private static DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        .appendPattern("[XXX]")
        .parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.UTC.getTotalSeconds())
        .toFormatter();

结果相同。