Java 8 LocalDateTime ZonedDateTime无法分析带时区的日期



我正在尝试使用Java 8新的Date模式而不是Joda,我遇到了以下问题:

两个

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z"))

LocalDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z"))

抛出"java.time.format.DateTimeParseException"异常。而

org.joda.time.DateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormat.forPattern("dd/MM/yy HH:mm.ss.SSS Z"))

工作良好。

异常原因是:

java.time.format.DateTimeParseException:在索引22 处无法解析文本"02/05/16 11:51.12.083+04:30"

我做错什么了吗?

如果您阅读了DateTimeFormatter的javadoc,您会发现一节详细介绍了如何使用Z偏移量(emphasis mine):

偏移Z:根据图案字母的数量设置偏移的格式。一个、两个或三个字母输出小时和分钟,不带冒号,例如"+0130"。当偏移量为零时,输出将为"+0000"。四个字母输出本地化偏移的完整形式,相当于偏移-O的四个字母。如果偏移量为零,则输出将是相应的本地化偏移量文本五个字母输出小时、分钟,可选秒(如果非零),冒号。如果偏移为零,则输出"Z"。六个或六个以上的字母抛出IllegalArgumentException。

因此,使用5个Z将按预期工作:

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30",
                    DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS ZZZZZ"));

请注意,您可以使用获得类似的结果

  • z
  • zz
  • zzz
  • zzzz
  • xxx
  • XXX
  • xxxxx
  • XXXXX

我在这篇文章中找到了答案,用冒号分隔时区

为了解析带有分号而不是DateFormatterjavadoc所指示的X或Z的时区的时间戳,您需要使用XXX。以下所有工作:

LocalDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX"))
OffsetDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX"))
ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX"))

使用DateTimeFormatterBuilder获得对解析器的精确控制并使用appendOffsetId工作:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
      .appendValue(ChronoField.DAY_OF_MONTH, 2)
      .appendLiteral('/')
      .appendValue(ChronoField.MONTH_OF_YEAR, 2)
      .appendLiteral('/')
      .appendValueReduced(ChronoField.YEAR, 2, 2, 2000)
      .appendLiteral(' ')
      .appendValue(ChronoField.HOUR_OF_DAY)
      .appendLiteral(':')
      .appendValue(ChronoField.MINUTE_OF_HOUR)
      .appendLiteral('.')
      .appendValue(ChronoField.SECOND_OF_MINUTE)
      .appendLiteral('.')
      .appendValue(ChronoField.MILLI_OF_SECOND)
      .appendLiteral(' ')
      .appendOffsetId()
      .toFormatter();
OffsetDateTime.parse("02/05/16 11:51.12.083 +04:30", formatter);

您需要使用XXX作为区域偏移。这将适用于ZonedDateTimeOffsetDateTime

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX"))

它也将使用LocalDateTime进行解析,但区域偏移量将被截断。

相关内容

  • 没有找到相关文章

最新更新