我們知道,springboot 有個配置時間格式的參數:spring.jackson.date-format。
通常使用方式是:
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
如果我需要傳 yyyy-MM-dd 格式的話,那就只能再加個 @JsonFormat 註解來爲它單獨指定格式。有沒有更方便的辦法呢?
❓ spring.jackson.date-format幫我們做了什麼?
到源碼中可以看到,date-format 原本應該是接收一個 DateFormat 的類路徑的,但我們一般寫的是一個時間格式字符串,所以默認使用的 DateFormat 的子類 SimpleDateFormat 來爲我們轉換時間格式。其實我們大可以傳一個自定義的 DateFormat 類進去。
💡 既然方案找到了,那麼實現起來就很簡單了,我們自定義一個類,繼承 DateFormat,但實際上,如果直接繼承 DateFormat 抽象類,你可能還需要像 SimpleDateFormat 一樣,在裏面需要自己初始化一堆複雜的參數,其實我們需要的僅僅是讓它支持多種時間格式,而 SimpleDateFormat 已經爲我們做好了這一切,不同的只是需要我們爲它指定不同的格式類型,所以,可以直接繼承 SimpleDateFormat,然後重寫它的 parse 和 format 方法即可達到我們的目的。
package com.yc.kfpt.webcommons.plugin;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 支持多種時間格式轉換,使用方法
* <code>
* spring:
* jackson:
* date-format: com.yc.kfpt.webcommons.plugin.DateFormatPlugin
* </code>
* @author 敖癸
* @formatter:on
* @since 2022/11/4
*/
public class DateFormatPlugin extends SimpleDateFormat {
private static final List<DateFormat> FORMATS = new ArrayList<>(5);
private static final String YYYY_MM = "^\\d{4}-\\d{1,2}$";
private static final String YYYY_MM_DD = "^\\d{4}-\\d{1,2}-\\d{1,2}$";
private static final String YYYY_MM_DD_HH_MM = "^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}$";
private static final String YYYY_MM_DD_HH_MM_SS = "^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$";
private static final String YYYY_MM_DD_HH_MM_SS_SSS = "^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}\\.\\d{3}$";
static {
FORMATS.add(new SimpleDateFormat("yyyy-MM"));
FORMATS.add(new SimpleDateFormat("yyyy-MM-dd"));
FORMATS.add(new SimpleDateFormat("yyyy-MM-dd HH:mm"));
FORMATS.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
FORMATS.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
}
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
return FORMATS.get(3).format(date, toAppendTo, fieldPosition);
}
@Override
public Date parse(String source, ParsePosition pos) {
String value = source.trim();
if ("".equals(value)) {
return null;
}
if (source.matches(YYYY_MM)) {
return FORMATS.get(0).parse(source, pos);
} else if