使用@JsonFormat轉換時間類型爲指定時間格式的字符串

背景

在我們的數據庫使用datatime等類型時,實體類需要使用Date或者LocalDateTime等相對應(當然也可以使用String,不過格式不受控制,而且有時候我們其他功能需要使用Date等類型,所以不推薦使用String),我們希望給調用者以我們希望的時間格式傳遞json,而不是默認的格式。
通常我們可能會使用for循環,遍歷每一個元素進行轉換,如下

List<User> users = xxx;
SimpleDateFormat fomatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (User user : users) {
	user.setLastLoginTimeStr(formatter.format(user.getLastLoginTime));
}

這種寫法的確可以實現我們的功能,但是比較繁瑣,不優雅,並且還需要新增其他輔助字段,所以我們並不希望使用這種寫法

使用@JsonFormat

使用一個組件或是jar時,就需要引入相應的依賴
如果是使用SpringBoot,在引用webstarter時,會自動引入com.fasterxml.jackson.core相關包,其中有一個@JsonFormat註解,我們可以使用它來幫助我們實現我們的功能

@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonFormat {
	...
    String pattern() default "";
    String timezone() default "##default";
    ...
}

我們主要關係以上兩個屬性

  • pattern:格式化表達式
  • timezone:時區

數據庫

我們創建一張表,名字以及字段無所謂,但需要包含兩個datetime類型的字段來進行測試
在這裏插入圖片描述

編寫實體類

我們使用一個Date以及一個LocalDateTime分別對應數據庫相應的列,然後標註@JsonFormat註解,兩個註解分別用不同的pattern來起到測試的目的

public User {
	...
	// 表示查詢時不查詢此字段
	@JsonFormat(pattern = "yyyyMMdd'T'HHmmss'Z'")
	private Date createTime;
	
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	private LocalDateTime updateTime;
	...
}

進行測試

接下來我們需要查詢實體,直接把實體返回查看json

@RestController
@AllArgsConstructor
public class TestController {
    private IUserService userService;

    @GetMapping("test/user")
    public List<User> test() {
        return userService.list();
    }
}

啓動項目,訪問路徑,看下結果
在這裏插入圖片描述
我們看到,兩個日期確實按照我們的指定的格式進行了轉換,證明@JsonFormat以及pattern有效,可以達到我們的目的。
但是事情還沒有結束,我們對比一下數據庫
在這裏插入圖片描述
可以看出LocalDateTime類型的updateTime字段和數據庫的值一致,但是Date類型的createTime卻比數據庫少了8個小時。一想差8小時,我們就應該明白這就是時區問題。Date類型把時間變爲了世界時GMT,而北京時間爲GMT+8
增加JsonFormattimezone屬性,如下

@JsonFormat(pattern = "yyyyMMdd'T'HHmmss'Z'", timezone="GMT+8")
private Date createDate;

再次運行,查看結果
在這裏插入圖片描述
可以看到時間已經正確了

小結

  • JsonFormat註解可以幫助我們實現日期轉化爲指定格式的時間字符串
  • pattern屬性指定時間格式,timezone屬性指定時區
  • LocalDateTime不會產生時區問題;Date會產生時區問題,需要使用timezone進行指定
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章