Set Jackson Timezone for Date deserialization

后端 未结 9 575
终归单人心
终归单人心 2020-12-13 04:23

I\'m using Jackson (via Spring MVC Annotations) to deserialize a field into a java.util.Date from JSON. The POST looks like - {\"enrollDate\":\"2011-09-28

相关标签:
9条回答
  • 2020-12-13 04:45

    If you really want Jackson to return a date with another time zone than UTC (and I myself have several good arguments for that, especially when some clients just don't get the timezone part) then I usually do:

    ObjectMapper mapper = new ObjectMapper();
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    dateFormat.setTimeZone(TimeZone.getTimeZone("CET"));
    mapper.getSerializationConfig().setDateFormat(dateFormat);
    // ... etc
    

    It has no adverse effects on those that understand the timezone-p

    0 讨论(0)
  • 2020-12-13 04:45

    For anyone struggling with this problem in the now (Feb 2020), the following Medium post was crucial to overcoming it for us.

    https://medium.com/@ttulka/spring-http-message-converters-customizing-770814eb2b55

    In our case, the app uses @EnableWebMvc and would break if removed so, the section on 'The Life without Spring Boot' was critical. Here's what ended up solving this for us. It allows us to still consume and produce JSON and XML as well as format our datetime during serialization to suit the app's needs.

    @Configuration
    @ComponentScan("com.company.branch")
    @EnableWebMvc
    public class WebMvcConfig implements WebMvcConfigurer {
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new MappingJackson2XmlHttpMessageConverter(
                    new Jackson2ObjectMapperBuilder()
                            .defaultUseWrapper(false)
                            .createXmlMapper(true)
                            .simpleDateFormat("yyyy-mm-dd'T'HH:mm:ss'Z'")
                            .build()
            ));
        converters.add(1, new MappingJackson2HttpMessageConverter(
                    new Jackson2ObjectMapperBuilder()
                            .build()
            ));
        }
    }
    
    0 讨论(0)
  • 2020-12-13 04:47

    Just came into this issue and finally realised that LocalDateTime doesn't have any timezone information. If you received a date string with timezone information, you need to use this as the type:

    ZonedDateTime

    Check this link

    0 讨论(0)
  • 2020-12-13 04:49

    Have you tried this in your application.properties?

    spring.jackson.time-zone= # Time zone used when formatting dates. For instance `America/Los_Angeles`
    
    0 讨论(0)
  • 2020-12-13 04:59

    In Jackson 2+, you can also use the @JsonFormat annotation :

    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone="America/Phoenix")
    private Date date;
    
    0 讨论(0)
  • 2020-12-13 05:00

    I am using Jackson 1.9.7 and I found that doing the following does not solve my serialization/deserialization timezone issue:

    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZ");
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    objectMapper.setDateFormat(dateFormat);
    

    Instead of "2014-02-13T20:09:09.859Z" I get "2014-02-13T08:09:09.859+0000" in the JSON message which is obviously incorrect. I don't have time to step through the Jackson library source code to figure out why this occurs, however I found that if I just specify the Jackson provided ISO8601DateFormat class to the ObjectMapper.setDateFormat method the date is correct.

    Except this doesn't put the milliseconds in the format which is what I want so I sub-classed the ISO8601DateFormat class and overrode the format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) method.

    /**
     * Provides a ISO8601 date format implementation that includes milliseconds
     *
     */
    public class ISO8601DateFormatWithMillis extends ISO8601DateFormat {
    
      /**
       * For serialization
       */
      private static final long serialVersionUID = 2672976499021731672L;
    
    
      @Override
      public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition)
      {
          String value = ISO8601Utils.format(date, true);
          toAppendTo.append(value);
          return toAppendTo;
      }
    }
    
    0 讨论(0)
提交回复
热议问题