本地日期时间解析

时间:2019-10-07 19:00:24

标签: java java-8 java-time zoneddatetime

我正在尝试将输入字符串解析为本地日期时间。

下面是我的代码

 ZonedDateTime z = ZonedDateTime.parse("2019-11-26T19:30:00Z", MY_DATE_TIME_FORMATTER);

其中

MY_DATE_TIME_FORMATTER= new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(ISO_LOCAL_DATE)
            .appendLiteral('T')
            .append(ISO_LOCAL_TIME)
            .appendLiteral('Z')
            .appendOffset("+HH:mm", "+0000")
            .toFormatter();

我收到以下异常

java.time.format.DateTimeParseException:无法在索引19处解析文本'2019-11-26T19:30:00Z'

您能告诉我我在做什么错吗?

3 个答案:

答案 0 :(得分:4)

Instant.parse

不需要格式化模式。

Instant.parse( "2019-11-26T19:30:00Z" ) 

您的输入格式符合ISO 8601标准。该特定格式的末尾有一个Z。该字母的意思是UTCoffset,零小时-分钟-秒),发音为“ Zulu”。

java.time 中的Instant类表示UTC中的时刻,始终为UTC。

使用ZonedDateTime类作为输入不是最合适的。我们有:

  • Instant表示始终以UTC表示的值。
  • OffsetDateTime仅适用于距UTC偏移量而不是时区的情况。当您需要更大的灵活性(例如生成各种格式的字符串)时,也可以将此类用于UTC值。 `instant.atOffset(
  • ZonedDateTime表示时区中的值。时区是特定区域的人们过去,现在和将来对偏移量的更改的历史。

Table of date-time types in Java, both modern and legacy

要查看调整到特定区域(时区)的人们所使用的偏移量的同一时刻,请应用ZoneId以获取ZonedDateTime对象。

Instant instant = Instant.parse( "2019-11-26T19:30:00Z" ) ;     // Default format for parsing a moment in UTC.
ZoneId z = ZoneId.of( "America/Edmonton" ) ;                    // A time zone is a history of past, present, and future changes to the offset used by the people of a particular region.
ZonedDateTime zdt = instant.atZone( z ) ;                       // Same moment, same point on the timeline, different wall-clock time.

请参阅此code run live at IdeOne.com

  

instant.toString():2019-11-26T19:30:00Z

     

zdt.toString():2019-11-26T12:30-07:00 [美国/埃德蒙顿]

答案 1 :(得分:2)

添加

.appendZoneOrOffsetId()

代替这两行:

.appendLiteral('Z')
.appendOffset("+HH:mm", "+0000")

整个构建器示例:

MY_DATE_TIME_FORMATTER= new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .append(ISO_LOCAL_DATE)
        .appendLiteral('T')
        .append(ISO_LOCAL_TIME)
        .appendZoneOrOffsetId()
        .toFormatter();

P.S。在您的特定情况下,我宁愿使用标准的ISO格式程序(如Hristo所述):

ZonedDateTime z = ZonedDateTime.parse("2019-11-26T19:30:00Z", DateTimeFormatter.ISO_ZONED_DATE_TIME);

此外,即使没有显式格式化程序,ZonedDateTime::parse方法也可以使用。由于默认使用它:

ZonedDateTime z = ZonedDateTime.parse("2019-11-26T19:30:00Z");

答案 2 :(得分:1)

使用内置的ISO时区格式化程序

    ZonedDateTime.parse("2019-11-26T19:30:00Z", DateTimeFormatter.ISO_ZONED_DATE_TIME);