Search code examples
javajsondatejackson

Jackson OffsetDateTime serialization Z instead of +00:00 timezone?


I'm using Spring Boot with the following ObjectMapper:

@Bean
public ObjectMapper objectMapper()
{
    final ObjectMapper mapper = new ObjectMapper();

    mapper.enable(SerializationFeature.INDENT_OUTPUT);

    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);  
    mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true)); // Makes no difference to output
    
    mapper.findAndRegisterModules();

    return mapper;
}

When OffsetDateTimes are serialized and returned in responses, they have a format like this:

"2020-02-28T12:28:29.01Z"
"2020-02-28T12:36:21.885Z"

I would have expected the timezone information at the end to look like this instead:

"2020-02-28T10:41:25.287+00:00"

Is there something I'm missing or doing wrong here, or anyway I can get the timezone information serialized as the +00:00 format instead of Z format?

Many thanks!


Solution

  • The following steps resolve this (taken from https://stackoverflow.com/a/41893238/12177456), thanks also @Ralf Wagner and @deHaar:

    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jsr310</artifactId>
      <version>2.6.5</version>
    </dependency>
    
    public class OffsetDateTimeSerializer extends JsonSerializer<OffsetDateTime>
    {
        private static final DateTimeFormatter ISO_8601_FORMATTER = DateTimeFormatter
            .ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx")
            .withZone(ZoneId.of("UTC"));
    
        @Override
        public void serialize(OffsetDateTime value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
        {
            if (value == null) {
                throw new IOException("OffsetDateTime argument is null.");
            }
    
            jsonGenerator.writeString(ISO_8601_FORMATTER.format(value));
        }
    }
    
    @Bean
    public ObjectMapper objectMapper()
    {
    
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objectMapper.registerModule(new JavaTimeModule());
        SimpleModule simpleModule = new SimpleModule();
    
        simpleModule.addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer());
        objectMapper.registerModule(simpleModule);
    
        return objectMapper;
    }