无法从类似'2016-07-02T00:00:00Z'的字符串中解析java.time.Instant

问题描述

在REST API响应中,我得到的日期为'2016-07-02T00:00:00Z'

代码中,我有一列如下所示

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss",timezone = "UTC")
private Instant effectiveDate;

// getter & setter  
public Instant getEffectiveDate() {
    return effectiveDate;
}

public OfferTerm setEffectiveDate(Instant effectiveDate) {
    this.effectiveDate = effectiveDate;
    return this;
}

得到以下错误

java.time.format.DateTimeParseException:无法解析文本'2016-07-02T00:00:00Z',未解析的文本位于索引19

在这里帮助我。

解决方法

您的日期时间字符串已经采用Instant#parse默认使用的格式。下面是演示该示例的演示:

import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2016-07-02T00:00:00Z";
        Instant instant = Instant.parse(strDateTime);
        System.out.println(instant);
    }
}

输出:

2016-07-02T00:00:00Z

由于Instant代表UTC时间线上的瞬时点(即,它独立于timezone),因此无需提及timezone = "UTC"。日期时间字符串中的Z已经指定了UTC。此外,模式"yyyy-MM-dd'T'HH:mm:ss"与日期时间字符串的模式不匹配。希望您了解,timezone使用patternInstant不仅是不必要的,而且是您所遇到错误的根本原因。

只需删除@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss",timezone = "UTC")即可解决问题。

,

在详细说明评论中的安德里亚斯答案之后,可能会提供以下摘要,以从包含时区信息的字符串中解析即时消息:

    如果输入字符串包含格式为@JsonFormatZ的时区信息,则可以省略
  1. ±[hh]:[mm]
class Wrapper {
    private Instant effectiveDate;
    // getter/setter
}

// Parseable JSON strings
String[] jsons = {
    "{\"effectiveDate\":\"2016-07-02T00:00:00Z\"}","{\"effectiveDate\":\"2016-07-05T00:00:00+00:00\"}","{\"effectiveDate\":\"2016-07-06T00:00:00+02:00\"}","{\"effectiveDate\":\"2016-07-07T00:00:00-02:00\"}",}; 

结果:

2016-07-02T00:00:00Z      -> 2016-07-02T00:00:00Z
2016-07-15T00:00:00+00:00 -> 2016-07-15T00:00:00Z
2016-07-16T00:00:00+02:00 -> 2016-07-15T22:00:00Z
2016-07-17T00:00:00-02:00 -> 2016-07-17T02:00:00

注意:此处无法解析诸如±[hh][mm]±[hh]之类的“快捷”时区。

  1. 如果时区后缀不可用(没有Z或时区)和/或快捷方式时区信息不可用,则需要采用以下格式:
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss['Z'][XXX][X]",timezone="UTC")
private Instant effectiveDate;

以下数据可以成功解析:

String[] jsons = {
    "{\"effectiveDate\":\"2016-07-02T00:00:00Z\"}",// Z
    "{\"effectiveDate\":\"2016-07-09T00:00:00\"}",// no timezone
    "{\"effectiveDate\":\"2016-07-10T00:00:00+01\"}",// +hh
    "{\"effectiveDate\":\"2016-07-11T00:00:00-09\"}",// -hh
    "{\"effectiveDate\":\"2016-07-12T00:00:00+0200\"}",// +hhmm
    "{\"effectiveDate\":\"2016-07-13T00:00:00-0400\"}",// -hhmm
    "{\"effectiveDate\":\"2016-07-15T00:00:00+00:00\"}",// +hh:mm
    "{\"effectiveDate\":\"2016-07-16T00:00:00+02:00\"}",// +hh:mm
    "{\"effectiveDate\":\"2016-07-17T00:00:00-02:00\"}"  // -hh:mm
};

解析结果:

2016-07-02T00:00:00Z      -> 2016-07-02T00:00:00Z
2016-07-09T00:00:00       -> 2016-07-09T00:00:00Z
2016-07-10T00:00:00+01    -> 2016-07-09T23:00:00Z
2016-07-11T00:00:00-09    -> 2016-07-11T09:00:00Z
2016-07-12T00:00:00+0200  -> 2016-07-11T22:00:00Z
2016-07-13T00:00:00-0400  -> 2016-07-13T04:00:00Z
2016-07-15T00:00:00+00:00 -> 2016-07-15T00:00:00Z
2016-07-16T00:00:00+02:00 -> 2016-07-15T22:00:00Z
2016-07-17T00:00:00-02:00 -> 2016-07-17T02:00:00Z
  1. (假设的)如果输入字符串中存在其他时区后缀,例如GMTUTC,并且带有可选的空格,则可以使用以下格式:
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss['Z'][[' ']['GMT']][[' ']['UTC'][XXX][X]",timezone="UTC")
private Instant effectiveDate;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...