【问题标题】:How to parse offset with colon using DateTimeFormatter?如何使用 DateTimeFormatter 用冒号解析偏移量?
【发布时间】:2019-08-31 03:18:51
【问题描述】:

我有以下字符串:String timeStamp = "2020-01-31 12:13:14 +03:00"。 我尝试使用 Java 8 DateTimeFormatter 解析它。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( format );
tmpTimestamp = ZonedDateTime.parse( timeStamp, formatter );

format 是其中之一:

"yyyy-MM-dd' 'HH:mm:ss' 'Z",
"yyyy-MM-dd' 'HH:mm:ss' 'X",
"yyyy-MM-dd' 'HH:mm:ss' 'x",
"yyyy-MM-dd HH:mm:ss Z",
"yyyy-MM-dd HH:mm:ss X",
"yyyy-MM-dd HH:mm:ss x",

没有一个工作。我总是得到DateTimeParseException 指向偏移子字符串“+03:00”中的“+”或“:”字符

根据 JavaDocs:Class DateTimeFormatter "+03:00" 应受以下任何一种支持:ZXx

那么问题是如何构造格式化字符串来解析它呢?

【问题讨论】:

  • @MS90 - 不是LocalDateTime,而是OffsetDateTime(因为它有一个偏移量)。

标签: java datetime parsing java-8 dateformatter


【解决方案1】:

来自javadoc

偏移 Z:这会根据图案的数量格式化偏移 字母。一个、两个或三个字母输出小时和分钟, 没有冒号,例如“+0130”。输出将是“+0000”时 偏移量为零。四个字母输出本地化的完整形式 offset,相当于四个字母的Offset-O。输出将是 如果偏移量为零,则对应的本地化偏移量文本。 五 字母输出小时,分钟,如果非零,则可选秒, 带冒号。 如果偏移量为零,则输出“Z”。六个或更多字母 抛出 IllegalArgumentException。

你需要 5 个 Z

String format = "yyyy-MM-dd HH:mm:ss ZZZZZ";

Demo

【讨论】:

    【解决方案2】:

    你应该使用时间Xyyyy-MM-dd HH:mm:ss XXX):

    String timeStamp = "2020-01-31 12:13:14 +03:00";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss XXX");
    ZonedDateTime tmpTimestamp = ZonedDateTime.parse(timeStamp, formatter);
    

    来自docs

    偏移 X 和 x:这会根据模式字母的数量来格式化偏移。

    一个字母只输出小时,例如“+01”,除非分钟不为零,在这种情况下分钟也会输出,例如“+0130”。

    两个字母输出小时和分钟,不带冒号,如'+0130'。

    三个字母输出小时和分钟,带冒号,如'+01:30'。

    四个字母输出小时和分钟以及可选的秒,不带冒号,例如'+013015'。

    五个字母输出小时和分钟以及可选的秒,带有冒号,例如'+01:30:15'。

    六个或更多字母会引发 IllegalArgumentException。

    当要输出的偏移量为零时,模式字母“X”(大写)将输出“Z”,而模式字母“x”(小写)将输出“+00”、“+0000”或'+00:00'。

    您也可以使用五个字母 (XXXXX),也可以使用 ZZZZZZZZ 代替 XXXXXXXX

    【讨论】:

      【解决方案3】:

      您不需要摆弄格式模式字符串。

          DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                  .append(DateTimeFormatter.ISO_LOCAL_DATE)
                  .appendLiteral(' ')
                  .append(DateTimeFormatter.ISO_LOCAL_TIME)
                  .appendLiteral(' ')
                  .appendOffsetId()
                  .toFormatter();
          String timeStampString = "2020-01-31 12:13:14 +03:00";
          OffsetDateTime dateTime = OffsetDateTime.parse(timeStampString, formatter);
          System.out.println(dateTime);
      

      它更冗长,但更难出错。我只是用内置部件组装格式化程序。输出是:

      2020-01-31T12:13:14+03:00

      我也在解析为OffsetDateTime 而不是ZonedDateTime。由于该字符串包含一个偏移量 (+03:00) 并且没有时区(例如 America/Boa_Vista),即使它可能与 ZonedDateTime 一起使用,OffsetDateTime 也是正确使用的类。

      【讨论】:

        猜你喜欢
        • 2017-12-31
        • 2013-04-26
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        • 2015-09-09
        • 2022-11-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多