Skip to content

How to resolve spring.jackson.date-format not working in Spring Boot

Problem

When I configured Spring Boot’s Jackson date formatting properties, the API still returned timestamps instead of formatted date strings. Here’s what I got:

{
"id": 1,
"createdDate": 1536124800000,
"modifiedDate": 1536211200000
}

I expected ISO-8601 formatted dates like 2018-09-05T08:00:00.000Z, but the response always showed numeric timestamps.

Environment

  • Spring Boot 2.x
  • Java 8+
  • Jackson 2.x

What happened?

I wanted to serialize dates in ISO-8601 format across my entire REST API. Since the domain classes were auto-generated by a legacy system, I couldn’t add @JsonFormat annotations to them. I tried configuring it via application properties:

application.yml
spring:
jackson:
serialization:
write-dates-as-timestamps: false
date-format: yyyy-MM-dd'T'HH:mm:ss.SSS'Z'

I also tried the properties format:

application.properties
spring.jackson.serialization.write-dates-as-timestamps=false
spring.jackson.date-format=yyyy-MM-dd'T'HH:mm:ss.SSS'Z'

I expected these settings to:

  • Disable timestamp serialization (write-dates-as-timestamps=false)
  • Apply the ISO-8601 format to all date fields

But when I called my API endpoint, I still got timestamps:

{
"createdDate": 1536124800000,
"modifiedDate": 1536211200000
}

How to solve it?

I tried to understand why the properties weren’t working. After some investigation, I found that Spring Boot’s auto-configuration can be overridden, and sometimes it doesn’t apply to all date types.

The reliable solution is to define a custom ObjectMapper bean:

JacksonConfig.java
package com.example.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class JacksonConfig {
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return mapper;
}
}

If you’re using Spring Boot’s Jackson2ObjectMapperBuilder, you can also do it this way:

JacksonConfig.java
package com.example.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
@Configuration
public class JacksonConfig {
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.build();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return objectMapper;
}
}

Now let me test again:

{
"id": 1,
"createdDate": "2018-09-05T08:00:00.000+00:00",
"modifiedDate": "2018-09-06T08:00:00.000+00:00"
}

The dates are now serialized in ISO-8601 format as expected.

The reason

I think the key reasons are:

  1. Property limitations: Spring Boot’s spring.jackson.* properties work through auto-configuration, but if you have any custom ObjectMapper bean definition, the auto-configuration gets overridden completely.

  2. Missing Jackson modules: For Java 8+ date types (like LocalDateTime, ZonedDateTime), you need the jackson-datatype-jsr310 module. Without it, Jackson doesn’t know how to serialize these types properly.

  3. Mixed date types: If you have both java.util.Date and java.time types, you need to ensure the right modules are registered. JavaTimeModule handles the modern date/time API.

  4. Bean priority: When you define a custom ObjectMapper bean, Spring uses it instead of the auto-configured one. That’s why you need to explicitly configure WRITE_DATES_AS_TIMESTAMPS in your bean.

Important dependencies

Make sure you have the necessary Jackson dependencies for Java 8 date/time support:

pom.xml
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

Or if using Gradle:

build.gradle
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'

Summary

In this post, I solved the problem of spring.jackson.date-format property not working by defining a custom ObjectMapper bean. The key point is that Spring Boot’s property-based configuration can be overridden, so defining your own bean with WRITE_DATES_AS_TIMESTAMPS disabled is the reliable approach. Don’t forget to register JavaTimeModule for Java 8+ date types.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments