【问题标题】:Jackson @JsonFormat converting date with incorrect timezoneJackson @JsonFormat 使用不正确的时区转换日期
【发布时间】:2019-08-18 14:01:29
【问题描述】:

我有一个来自 JSON 有效负载的值:

"callStartTime" : "2019-03-27 13:00:00"

Entity.java

@JsonProperty("callStartTime")
@Column(name = "call_start_dt", nullable = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private Date callStartTime;

当我在控制台上打印它时,它说:

Wed Mar 27 08:00:00 CDT 2019

我想和 json 有效负载中的一样。我该如何解决?

我只是从 json 中获取日期并将其写入 mysql db 中的 datetime 列。

【问题讨论】:

标签: java spring date jackson annotations


【解决方案1】:

简单的解决方案:我通过将数据类型更改为 String 来解决它,这完成了我捕获来自 JSON 有效负载的值的目标。使用Date 和其他数据类型将值转换为不同的时区。

@JsonProperty("callStartTime")
@Column(name = "call_start_dt", nullable = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private **String** callStartTime;

【讨论】:

    【解决方案2】:

    试试这个

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
    private Date callStartTime;
    

    【讨论】:

    • 抛出异常。 exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.util.Date` 来自字符串“2019-03-27T13:00:00Z”:预期格式“yyyy-MM-dd'T'HH:mm:ss.SSSXXX”`
    • 啊,你的日期没有毫秒,使用 yyyy-MM-dd'T'HH:mm:ss.XXX
    • 如果你使用 java 版本 >= 1.8 使用 ZonedDateTime 而不是 Date @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.XXX ") 私有 ZonedDateTime callStartTime;
    • 仍然会引发异常。同上
    【解决方案3】:

    java.util.Date 不捕获时区数据。它只知道自纪元以来的毫秒数。

    您可以尝试使用jackson-modules-java8 中的模块之一,然后反序列化为ZonedDateTime 的实例,它可以识别时区。

    编辑:试试这个作为让它工作的基础:

    public class SoTest {
        public static void main(String[] args) throws Exception {
            ObjectMapper om = new ObjectMapper().registerModule(new ParameterNamesModule())
                                                .registerModule(new JavaTimeModule());
    
            String s = "{\"callStartTime\" : \"2019-03-27T13:00:00Z\" }";
    
            MyType mt = om.readValue(s, MyType.class);
    
            System.out.println(mt.getCallStartTime());
        }
    }
    
    class MyType {
        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssX", lenient = OptBoolean.FALSE)
        private ZonedDateTime callStartTime;
    
        public ZonedDateTime getCallStartTime() {
            return callStartTime;
        }
    
        public void setCallStartTime(ZonedDateTime date) {
            this.callStartTime = date;
        }
    
    }
    

    【讨论】:

    • 出现异常。 Cannot deserialize value of type java.time.ZonedDateTime from String "2019-03-27T13:00:00Z": Text '2019-03-27T13:00:00Z' could not be parsed, unparsed text found at index 19; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.time.ZonedDateTime from String "2019-03-27T13:00:00Z": Text '2019-03-27T13:00:00Z' could not be parsed, unparsed text found at index 19
    • 还添加了jackson-modules-8中提到的所有3个依赖项
    • 我没有使用 ObjectMapper。它是如何注册的?我只是从 json 中获取日期并将其写入日期时间列中的 mysql db。
    • 您对@JsonProperty (fasterxml.github.io/jackson-annotations/javadoc/2.8/com/…) 的使用表明某处正在使用Jackson 进行JSON 解析,这反过来意味着正在使用ObjectMapper。
    • 好的,知道了。但仍然得到这个异常。我该如何解决?
    【解决方案4】:

    对此有两种可能的解决方案:

    1.定义 ObjectMapper bean 并设置日期格式。

    @Bean
    public ObjectMapper objectMapper()
    {
       ObjectMapper objectMapper = new ObjectMapper();
    
       DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
       objectMapper.setDateFormat(df);
           return objectMapper;
    }
    

    2。使用@JsonFormat 为特定字段设置日期格式

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
    private Date createTime;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-19
      • 1970-01-01
      • 1970-01-01
      • 2015-10-27
      • 1970-01-01
      • 2023-04-07
      • 2012-10-31
      • 1970-01-01
      相关资源
      最近更新 更多