[英]Inconsistent behaviour of Jackson's JsonFormat for Old Date API and ZonedDateTime
I was trying to use Jackson's JsonFormat annotation in my POJO class to serialize the ZonedDateTime into a different timezone.我试图在我的POJO class 中使用 Jackson 的 JsonFormat 注释将 ZonedDateTime 序列化为不同的时区。 (Say the timezone in ZonedDateTimeZone is ET, I want to serialize it in UTC) (假设 ZonedDateTimeZone 中的时区是 ET,我想将其序列化为 UTC)
My POJO:我的POJO:
package com.example.demo;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
import java.time.ZonedDateTime;
package com.example.demo;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
import java.time.ZonedDateTime;
public class POJO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSZ", timezone = "UTC")
private ZonedDateTime zonedDateTimeWithPatternAndTimeZoneInJsonFormat;
@JsonFormat(timezone = "UTC")
private ZonedDateTime zonedDateTimeWithTimeZoneInJsonFormat;
private ZonedDateTime zonedDateTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSZ", timezone = "UTC")
private Date oldDateWithTimeZoneAndPatternInJsonFormat;
@JsonFormat(timezone = "UTC")
private Date oldDateWithTimeZoneInJsonFormat;
private Date oldDate;
// getters and setters below
}
Main Method主要方法
package com.example.demo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.*;
import java.util.TimeZone;
package com.example.demo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
//@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.setTimeZone(TimeZone.getDefault());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
LocalDateTime ldt = LocalDateTime.of(2020, Month.JUNE.getValue(), 12, 15, 0 , 0);
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("America/New_York"));
Date oldDate = Date.from(zdt.toInstant());
System.out.println("old Date with System's time zone" + oldDate);
POJO pojo = new POJO();
pojo.setOldDate(oldDate);
pojo.setOldDateWithTimeZoneAndPatternInJsonFormat(oldDate);
pojo.setOldDateWithTimeZoneInJsonFormat(oldDate);
pojo.setZonedDateTimeWithPatternAndTimeZoneInJsonFormat(zdt);
pojo.setZonedDateTimeWithTimeZoneInJsonFormat(zdt);
pojo.setZonedDateTime(zdt);
System.out.println(objectMapper.writeValueAsString(pojo));
}
}
Output: Output:
old Date with System's time zoneSat Jun 13 00:30:00 IST 2020
{
"zonedDateTimeWithPatternAndTimeZoneInJsonFormat": "2020-06-12 19:00:00.000+0000",
"zonedDateTimeWithTimeZoneInJsonFormat": "2020-06-12T15:00:00-04:00",
"zonedDateTime": "2020-06-12T15:00:00-04:00",
"oldDateWithTimeZoneAndPatternInJsonFormat": "2020-06-12 19:00:00.000+0000",
"oldDateWithTimeZoneInJsonFormat": "2020-06-12T19:00:00.000+00:00",
"oldDate": "2020-06-13T00:30:00.000+05:30"
}
As you can see in output, if i only specify timezone and not pattern, the oldDateWithTimeZone is serialized in UTC timezone but for ZonedDateTime only specifying timezone doesn't serialize it in specified timezone.正如您在 output 中看到的,如果我只指定时区而不指定模式,则 oldDateWithTimeZone 在 UTC 时区中序列化,但对于 ZonedDateTime,仅指定时区不会在指定时区中序列化它。 But if you specify pattern as well, It respects the specified timezone.但是,如果您也指定模式,它会遵守指定的时区。
Seems like it's an issue in jackson-databind.似乎这是 jackson-databind 中的一个问题。 Reported the issue on https://github.com/FasterXML/jackson-databind/issues/2799 .在https://github.com/FasterXML/jackson-databind/issues/2799上报告了该问题。
As mentioned in question's comments section, Specifying timezone along with pattern, ie @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSZ", timezone = "UTC")
works as expected.如问题评论部分所述,指定时区和模式,即@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSZ", timezone = "UTC")
按预期工作。 I earlier tried just with timezone.我之前只尝试过时区。
@JsonFormat(timezone= "UTC")
sets your timezone when serializing date, not format. @JsonFormat(timezone= "UTC")
在序列化日期时设置您的时区,而不是格式。 If you want to change format i suggest using如果你想改变格式我建议使用
@JsonSerialize(using = CustomDateSerializer.class)
With implementation of CustomDateSerializer
随着CustomDateSerializer
的实施
class CustomDateSerializer extends StdSerializer<ZonedDateTime> {
public CustomDateSerializer(Class<ZonedDateTime> t) {
super(t);
}
public CustomDateSerializer() {
this(null);
}
@Override
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
LocalDateTime utc = LocalDateTime.ofInstant(value.toInstant(), ZoneId.of("UTC"));
gen.writeString("##date format here##");
}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.