Date Formatting Techniques in Spring Boot Applications
This article explains why consistent date formatting is crucial in Spring Boot APIs, outlines common scenarios such as front‑end data exchange, database storage and logging, and presents multiple server‑side and client‑side solutions—including SimpleDateFormat, DateTimeFormatter, global Jackson settings, annotations, custom converters, and timestamp output—complete with code examples.
In Spring Boot development, formatting the date returned by APIs is essential for data readability and maintainability across different systems, especially in front‑end/back‑end separated projects where inconsistent date formats can cause display and processing issues.
Typical use cases include front‑end/back‑end data exchange, database storage and queries, and log recording, all of which benefit from a unified date format.
Spring Boot provides several approaches to achieve date formatting, such as configuration‑file settings, annotations, and global formatters, allowing developers to choose the method that best fits their needs.
Front‑end Date Formatting
function dateFormat(fmt, date) {
let ret;
const opt = {
"Y+": date.getFullYear().toString(),
"m+": (date.getMonth() + 1).toString(),
"d+": date.getDate().toString(),
"H+": date.getHours().toString(),
"M+": date.getMinutes().toString(),
"S+": date.getSeconds().toString()
};
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) {
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")));
};
};
return fmt;
}
let date = new Date();
dateFormat("YYYY-mm-dd HH:MM:SS", date);
// >>> 2021-07-25 21:45:12SimpleDateFormat Formatting (pre‑JDK 8)
// Define formatter
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Format a Date object
String date = dateFormat.format(new Date());In a Spring controller, you can format fields of a list of entities as follows:
@RequestMapping("/list")
public List
getList() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List
list = userMapper.getList();
list.forEach(item -> {
item.setCtime(dateFormat.format(item.getCreatetime()));
item.setUtime(dateFormat.format(item.getUpdatetime()));
});
return list;
}DateTimeFormatter Formatting (JDK 8+)
@RequestMapping("/list")
public List
getList() {
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
List
list = userMapper.getList();
list.forEach(item -> {
item.setCtime(dateFormat.format(item.getCreatetime()));
item.setUtime(dateFormat.format(item.getUpdatetime()));
});
return list;
}DateTimeFormatter is thread‑safe and works with the new java.time types such as LocalDateTime, whereas SimpleDateFormat works with the legacy Date class.
Global Date Formatting via Configuration Files
# application.properties
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8Jackson automatically applies this format to all date fields when serializing JSON responses, providing a uniform output without additional code.
Partial Field Formatting with @JsonFormat
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
@Data
public class UserInfo {
private int id;
private String username;
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone = "GMT+8")
private Date createtime;
private Date updatetime;
}Custom Parameter Converters
@Configuration
public class DateConverterConfig {
@Bean
public Converter
localDateConverter() {
return source -> LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
@Bean
public Converter
localDateTimeConverter() {
return source -> LocalDateTime.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}When using lambda expressions, ensure the target type is correctly inferred; otherwise, prefer anonymous inner classes or register the converters after RequestMappingHandlerAdapter is initialized.
Spring Annotation @DateTimeFormat
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthday;The pattern must match the incoming string format, otherwise a conversion exception will be thrown.
ControllerAdvice with initBinder
@ControllerAdvice
public class InitBinderDateController {
@InitBinder("date")
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(LocalDateTime.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) {
if (!StringUtils.isEmpty(text)) {
setValue(LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
}
});
}
}Backend Global Settings via Beans
@Configuration
public class LocalDateTimeSerializerConfig {
private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
@Bean
public LocalDateTimeSerializer localDateTimeSerializer() {
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(PATTERN));
}
@Bean
public LocalDateTimeDeserializer localDateTimeDeserializer() {
return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(PATTERN));
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());
};
}
}Returning Dates as Timestamps
# application.properties
spring.mvc.format.date=unixExample controller:
@RestController
public class MyController {
@GetMapping("/entity")
public MyEntity getEntity() {
MyEntity entity = new MyEntity();
entity.setDate(new Date());
return entity;
}
}The response will contain the date field as a Unix timestamp, e.g., { "date": 1678912345678 }.
Top Architecture Tech Stack
Sharing Java and Python tech insights, with occasional practical development tool tips.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.