【问题标题】:Jackson @JsonFormat set date with one day lessJackson @JsonFormat 设置日期少一天
【发布时间】:2015-10-27 15:51:21
【问题描述】:

我在我的项目中使用了 Spring Date Rest 和 Spring Boot。 这个项目有一个对象,我使用注释 @JsonFormat 来格式化将从我的 Json 接收到的日期字段。 字段日期的格式为“dd/MM/yyyy”。 当我在我的 json 中发送值“08/07/1980”时,Jackson 会转换为值“07/07/1980”。

问题是@JsonFormat 设置的日期少了一天

这是我的源代码

@Temporal(TemporalType.DATE)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "UTC")
private Date birthDate;

谢谢

【问题讨论】:

  • 我猜你的意思是在向后端执行请求时。客户端是浏览器还是某种 REST 工具?客户端和服务器是否在同一时区?
  • 我的第一个猜测是,由于您使用 UTC 并省略小时和秒,因此应用巴西和 UTC 之间的偏移量会导致时间信息丢失。作为快速尝试,您可以从注释中省略 locale 属性并使用此模式代替“yyyy-MM-dd'T'HH:mm:ss.SSSZ”,其中包括时区信息和毫秒,因此客户端的表示无关紧要选择

标签: json format jackson spring-boot spring-data-rest


【解决方案1】:

使用这个解决方案,它比我的解决方案更有效和现代:https://stackoverflow.com/a/45456037/4886918

感谢@Benjamin Lucidarme。

我使用以下方法解决了我的问题:

@Temporal(TemporalType.DATE)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "Brazil/East")
private Date birthDate;

我将时区更改为“巴西/东部”或“美国/圣保罗”并开始工作

谢谢

【讨论】:

  • 同样的问题,同样的解决方案:))
【解决方案2】:

@William 的回答有效,但您应该将这些行添加到您的 application.properties 文件中:

spring.jackson.time-zone=Brazil/East
spring.jackson.locale=pt-BR

这样一来,您只需指定一次时区和语言环境,并且它适用于您申请的所有日期。

【讨论】:

  • 谢谢,您的解决方案更加有效和现代
  • 这样一个简单而优雅的解决方案。谢谢!!
【解决方案3】:

我会将ObjectMapper 时区设置为默认 JVM 时区:

    ObjectMapper objectMapper = new ObjectMapper();
    //Set default time zone as JVM timezone due to one day difference between original date and formatted date.
    objectMapper.setTimeZone(TimeZone.getDefault());

如果您不知道服务器环境使用的时区,这是一个更好的解决方案。

在spring-boot 环境中,您可以覆盖默认的JacksonAutoConfiguration:

@Bean
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    return builder.createXmlMapper(false)
            // Set timezone for JSON serialization as system timezone
            .timeZone(TimeZone.getDefault())
            .build();
}

【讨论】:

    【解决方案4】:

    在双方(客户端 - 服务器)上注释您提交的日期,如下所示:

    @JsonDeserialize(using = JsonDateDeserializer.class)
    @JsonSerialize(using = JsonDateSerializer.class)
    private Date birthDate;
    

    并在双方再次将此实现用于序列化和反序列化:

    public class JsonDateSerializer extends JsonSerializer<Date> {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
    
        @Override
        public void serialize(final Date date, final JsonGenerator gen, final SerializerProvider provider) throws IOException, JsonProcessingException {
    
            String dateString = format.format(date);
            gen.writeString(dateString);
        }
    
    }
    
    
    public class JsonDateDeserializer extends JsonDeserializer<Date> {
    
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
    
        @Override
        public Date deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
            if (jp.getCurrentToken().equals(JsonToken.VALUE_STRING)) {
                try {
                    Date date = format.parse(jp.getText().toString());
                    return date;
                } catch (ParseException e) {
                    //e.printStackTrace();
                }
            }
            return null;
        }
    
    }
    

    【讨论】:

      【解决方案5】:

      我也遇到过类似的问题。我想为这个问题添加的所有答案都是针对上述问题的,我的解决方案将解释该问题并提供通用解决方案。

      当您对同一 Date 使用 2 个不同的时区时,您可能会遇到此问题。 当您执行new Date() 时,除非您明确指定时区,否则它将使用您的默认时区。 Lemme 用代码-sn-p 向您解释这一点,(您在印度,当前日期是(2021 年 9 月 5 日,IST 上午 12 点)

      // 09/05/2021 00:00:00 IST
      Date birthDate = new Date();
      

      现在,当将birthDate 设置为模型并使用 JsonFormat 对其进行序列化时。默认情况下,JsonFormat 使用 UTC 时区。

      @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
      private Date birthDate;
      

      序列化将产生08/05/2021,而不是09/05/2021。
      让我用08/05/2021 UTC 和09/05/2021 IST 的时区写日期。
      让我也为日期添加时间,08/05/2021 18:30:00 UTC 和 09/05/2021 00:00:00 IST。
      现在你明白为什么会发生了,如果你看到日期是正确的,但有不同的时区。有两种方法可以处理这个问题,

      1. 使用相同的时区
      2. 在序列化日期时也添加时间和时区。喜欢08/05/2021 18:30:00 UTC 和09/05/2021 00:00:00 IST

      【讨论】:

        猜你喜欢
        • 2022-12-19
        • 1970-01-01
        • 1970-01-01
        • 2019-08-18
        • 1970-01-01
        • 1970-01-01
        • 2017-10-06
        • 2017-08-25
        • 2016-01-03
        相关资源
        最近更新 更多