Backend Development 9 min read

How to Simplify Date Formatting in Spring Boot: Global Config & @JsonFormat Tricks

This article shares practical techniques for handling date and time in Spring Boot projects, including the pitfalls of using SimpleDateFormat, the benefits of @JsonFormat, and two approaches to global configuration that streamline formatting for both java.util.Date and java.time types.

macrozheng
macrozheng
macrozheng
How to Simplify Date Formatting in Spring Boot: Global Config & @JsonFormat Tricks

Preface

After several senior colleagues left the department, I inherited their projects and immediately noticed a recurring problem: almost every date formatting operation used

SimpleDateFormat

, leading to verbose and error‑prone code.

A Pitfall

Our monthly code‑review sessions often require us to optimize others' code. Refactoring date handling is especially painful because many modules still rely on

java.util.Date

and

java.util.Calendar

, which are not thread‑safe and lack time‑zone support. The team now mandates the use of the JDK 1.8+

java.time

API, such as

LocalDateTime

, but legacy code persists.

<code>SvcOrderDailyStatisticsPo orderDailyStatisticsPo = new SvcOrderDailyStatisticsPo();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date stationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));
orderDailyStatisticsPo.setStatisticalDate(stationTime);
</code>

Mixing

java.util.Date

,

java.util.Calendar

, and the newer

java.time

types makes calculations cumbersome.

Optimization Strategies

Because date formatting is used so frequently, we should abstract it into a global utility. Below are several practical solutions demonstrated with code.

Test endpoint:

http://127.0.0.1:8080/timeTest
<code>@GetMapping("/timeTest")
public OrderInfo timeTest() {
    OrderInfo order = new OrderInfo();
    order.setCreateTime(LocalDateTime.now());
    order.setUpdateTime(new Date());
    return order;
}
</code>

1. Using @JsonFormat Annotation

The

@JsonFormat

annotation is a common, straightforward way to control JSON serialization of date fields.

<code>public class OrderInfo {
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    public LocalDateTime getCreateTime() { return createTime; }
    public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
    public Date getUpdateTime() { return updateTime; }
    public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
}
</code>

While this works, it requires adding the annotation to every date field, which can be repetitive.

2. Global Configuration (1)

Spring Boot already provides a property

${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}

. By defining a configuration class that registers a

LocalDateTimeSerializer

bean, we can apply this format globally without annotating each field.

<code>public class OrderInfo {
    // @JsonFormat(...) // not needed after global config
    private LocalDateTime createTime;
    private Date updateTime;
    // getters and setters omitted for brevity
}
</code>
<code>@Configuration
public class LocalDateTimeSerializerConfig {
    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

    @Bean
    public LocalDateTimeSerializer localDateTimeDeserializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
    }
}
</code>

This configuration supports both

Date

and

LocalDateTime

. However, some fields may require a different pattern such as

yyyy-MM-dd

, which can be handled by adding

@JsonFormat

on those specific fields.

3. Global Configuration (2)

A similar global setup can be created with a primary

ObjectMapper

. After applying this configuration, the

@JsonFormat

annotation on individual fields no longer takes effect.

<code>public class OrderInfo {
    private LocalDateTime createTime;
    private Date updateTime;
    // getters and setters omitted
}
</code>
<code>@Configuration
public class LocalDateTimeSerializerConfig {
    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

    @Bean
    @Primary
    public ObjectMapper serializingObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    }

    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeString(value.format(DateTimeFormatter.ofPattern(pattern)));
        }
    }

    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern(pattern));
        }
    }
}
</code>

Conclusion

The post shares a practical Spring Boot tip for handling date and time globally, reflects on the challenges of optimizing legacy code, and demonstrates how such refactoring can improve development efficiency and personal skill growth.

JavaBackend DevelopmentSpring BootLocalDateTimedate formatting@JsonFormatGlobal Configuration
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.