Backend Development 11 min read

Configuring Date Formatting in SpringBoot Applications

This article explains how to customize the date format returned by SpringBoot REST controllers using configuration files, Jackson annotations, JavaBean annotations, and global converters, covering both JSON serialization and form data binding with practical code examples.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Configuring Date Formatting in SpringBoot Applications

1. SpringBoot Setting Backend to Frontend Date Format

In a SpringBoot application, the default JSON serialization of @RestController outputs dates in the ISO‑8601 format like 2020-12-03T15:12:26.000+00:00 , which often needs to be converted to a more readable pattern.

Method 1: Configuration File Modification

Configure the date format in application.yml :

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss  #统一转换为指定格式
    time-zone: GMT+8                 #时区修改为东8区

Or in application.properties :

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss  #统一转换为指定格式
spring.jackson.time-zone=GMT+8                 #时区修改为东8区
Note: The time‑zone must be set to avoid an 8‑hour offset caused by the database defaulting to UTC.

Method 2: Adding Annotations on JavaBean Entities

I. @JsonFormat Annotation

Apply @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") on a field or getter to control JSON output:

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;

II. @DateTimeFormat Annotation

Use @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") on a Date property to parse incoming form data:

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthday;

III. @Temporal Annotation

The JPA @Temporal annotation can also define the temporal type, e.g.:

@Temporal(TemporalType.TIMESTAMP)
private Date createTime;

2. SpringBoot Global Date Converter Configuration

Configure converters to transform String parameters and JSON dates into Date objects globally.

2.1 Converter for Form String to Date

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class GlobalFormDateConvert implements Converter
{
    private static final List
paramList = new ArrayList<>();
    private static final String param1 = "yyyy-MM";
    private static final String param2 = "yyyy-MM-dd";
    private static final String param3 = "yyyy-MM-dd HH:mm";
    private static final String param4 = "yyyy-MM-dd HH:mm:ss";
    static {
        paramList.add(param1);
        paramList.add(param2);
        paramList.add(param3);
        paramList.add(param4);
    }
    public Date parseDate(String source, String format) {
        try {
            DateFormat dateFormat = new SimpleDateFormat(format);
            return dateFormat.parse(source);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    @Override
    public Date convert(String source) {
        if (StringUtils.isEmpty(source)) return null;
        source = source.trim();
        if (source.matches("^\\d{4}-\\d{1,2}$")) return parseDate(source, paramList.get(0));
        if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) return parseDate(source, paramList.get(1));
        if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}$")) return parseDate(source, paramList.get(2));
        if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$")) return parseDate(source, paramList.get(3));
        throw new IllegalArgumentException("Unsupported date format: " + source);
    }
}

2.2 Global JSON Date Converter

import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.databind.util.StdDateFormat;
import org.springframework.util.StringUtils;

public class GlobalJsonDateConvert extends StdDateFormat {
    public static final GlobalJsonDateConvert instance = new GlobalJsonDateConvert();
    @Override
    public Date parse(String dateStr, ParsePosition pos) {
        return getDate(dateStr, pos);
    }
    @Override
    public Date parse(String dateStr) {
        return getDate(dateStr, new ParsePosition(0));
    }
    private Date getDate(String dateStr, ParsePosition pos) {
        if (StringUtils.isEmpty(dateStr)) return null;
        SimpleDateFormat sdf = null;
        if (dateStr.matches("^\\d{4}-\\d{1,2}$")) sdf = new SimpleDateFormat("yyyy-MM");
        else if (dateStr.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) sdf = new SimpleDateFormat("yyyy-MM-dd");
        else if (dateStr.matches("^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}$")) sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        else if (dateStr.matches("^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$")) sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        else if (dateStr.length() == 23) sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        if (sdf != null) return sdf.parse(dateStr, pos);
        return super.parse(dateStr, pos);
    }
    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date, toAppendTo, fieldPosition);
    }
    @Override
    public GlobalJsonDateConvert clone() {
        return new GlobalJsonDateConvert();
    }
}

2.3 Registering Converters in Spring

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xgf.online_mall.convert.GlobalFormDateConvert;
import com.xgf.online_mall.convert.GlobalJsonDateConvert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Configuration
public class WebConfig {
    @Bean
    public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = new ObjectMapper();
        mapper.setDateFormat(GlobalJsonDateConvert.instance);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        converter.setObjectMapper(mapper);
        List
list = new ArrayList<>();
        list.add(MediaType.APPLICATION_JSON_UTF8);
        converter.setSupportedMediaTypes(list);
        return converter;
    }
    @Bean
    @Autowired
    public ConversionService getConversionService(GlobalFormDateConvert globalDateConvert) {
        ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
        Set
converters = new HashSet<>();
        converters.add(globalDateConvert);
        factoryBean.setConverters(converters);
        return factoryBean.getObject();
    }
}

By applying the above configurations, SpringBoot will uniformly format dates in JSON responses and correctly parse date strings from form submissions, eliminating the default ISO‑8601 representation and handling time‑zone discrepancies.

backendJavaAnnotationsSpringBootdateformatJackson
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.