Java8- ZonedDateTime 与 DateTimeFormatter 无法识别格式

Posted

技术标签:

【中文标题】Java8- ZonedDateTime 与 DateTimeFormatter 无法识别格式【英文标题】:Java8- ZonedDateTime with DateTimeFormatter not recognizing the format 【发布时间】:2016-05-02 10:37:15 【问题描述】:

我正在使用带有 Java 8 的 DateTimeFormatter 的 ZonedDateTime。当我尝试解析我自己的模式时,它无法识别并引发异常。

    String oraceDt = "1970-01-01 00:00:00.0";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
    ZonedDateTime dt = ZonedDateTime.parse(oraceDt, formatter);

Exception in thread "main" java.time.format.DateTimeParseException: Text '1970-01-01 00:00:00.0' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: ,ISO resolved to 1970-01-01T00:00 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)
at com.timezone.Java8DsteTimes.testZonedDateTime(Java8DsteTimes.java:31)
at com.timezone.Java8DsteTimes.main(Java8DsteTimes.java:11)

原因:java.time.DateTimeException:无法从 TemporalAccessor: 获取 ZonedDateTime,ISO 解析为 java.time.format.Parsed 类型的 1970-01-01T00:00

【问题讨论】:

【参考方案1】:

好吧,您想创建一个 ZonedDateTime,它始终引用一个时区,但您的输入不包含此类信息,并且您也没有指示格式化程序在输入缺少时区时使用默认时区。您的问题有两种解决方案:

    指示您的解析器使用时区(此处以系统 tz 为例)

    String oraceDt = "1970-01-01 00:00:00.0";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
    ZonedDateTime zdt = 
      ZonedDateTime.parse(oraceDt, formatter.withZone(ZoneId.systemDefault()));
    System.out.println(zdt); // in my default zone => 1970-01-01T00:00+01:00[Europe/Berlin]
    

    使用另一个不需要时区的结果类型(此处为LocalDateTime

    String oraceDt = "1970-01-01 00:00:00.0";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
    LocalDateTime ldt = LocalDateTime.parse(oraceDt, formatter);
    System.out.println(ldt); // 1970-01-01T00:00
    

【讨论】:

谢谢 Meno..我选择选项 1,因为我需要通过时区。创建 ZoneId 对象并传递给它。 ZoneId zoneId = ZoneId.of(ZoneId.SHORT_IDS.get("CST"));【参考方案2】:

这是一个使用 ZonedDateTime 和 Java 8 的 DateTimeFormatter 的小例子。

public String currentDateTime() 

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("EEEE y-MM-d MMMM HH:m:s z Z'['VV']' 'Day:'D");

return ZonedDateTime.now(ZoneId.of("Europe/Lisbon")).format(dateTimeFormatter);
    

ZonedDateTime 类允许您创建带有时区的日期/时间对象。将使用默认时区;即您在计算机上建立的时区。您可以使用 DateTimeFormatter 类来显示时区。在 Java 代码中,时区显示为区域偏移、区域名称和区域 ID。请注意,日期时间格式化程序模式分别为“Z”、“z”和“VV”。该程序还创建一个日期/时间对象,然后使用 ZoneId 类的 of 方法添加区域 ID。最后,使用 ZoneOffset 类的 of 方法将时区添加到另一个日期/时间对象。

【讨论】:

以上是关于Java8- ZonedDateTime 与 DateTimeFormatter 无法识别格式的主要内容,如果未能解决你的问题,请参考以下文章

Java 8:如何从 Epoch 值创建 ZonedDateTime?

Java 8 - ZonedDateTime 的 DateTimeFormatter 和 ISO_INSTANT 问题

Java 8 Time API - ZonedDateTime - 解析时指定默认 ZoneId

Java 8:计算两个 ZonedDateTime 之间的差异

将 java.sql.Timestamp 转换为 Java 8 ZonedDateTime?

ZonedDateTime 到 UTC 并应用了偏移量?