@DateTimeFormat 和 @JsonFormat 的詳細研究,以及timezone="GMT+8"的研究,時區問題(1)

注意:以下所有的內容,是通過實驗得出,並進行總結,如有錯誤,請指正

前置知識

CST是什麼

後續的0時區,就是中時區,就是國際時間,就是UTC+0

@DateTimeFormat

注意:url拼接的參數才生效

正確用法:

例如:

  • 請求URL : http://localhost:9999/put?date=2020-03-07 13:13:13

  • 後端代碼

@PostMapping("put")
public User put(@DateTimeFormat(pattern = "yyyy-MM-dd HH") @RequestParam Date  date){
       System.out.println(date); // Sat Mar 07 13:00:00 CST 2020  // 可以看到分和秒都被忽略了。
}

錯誤用法

  • 放在請求體或者表單
class User{
	@DateTimeFormat(pattern = "yyyy-MM-dd")  // 這樣沒有作用
   		private Date date;
   		/*getter setter*/
}

總結:

	@DateTimeFormat 的作用只是將路徑請求參數的字符串轉成想要格式的Date對象。

@JsonFormat

注意:

  1. 不可用於url的路徑參數。也就是說像@DateTimeFormat那樣用不可以。
  2. timezone解釋:
    意思是用於序列化時,指定這個默認時區,也就是傳進來的字符串的時區。默認是UTC就是:0時區。(因爲服務器也有一個時區,所以要根據傳進值的時區,進行轉換,後續詳細演示)
    源碼註釋:
/**
 * {@link java.util.TimeZone} to use for serialization (if needed).
 * Special value of  {@link #DEFAULT_TIMEZONE}
 * can be used to mean "just use the default", where default is specified
 * by the serialization context, which in turn defaults to system
 * default (UTC) unless explicitly set to another timezone.
 */
public String timezone() default DEFAULT_TIMEZONE;

正確用法1,輸入

未指定timezone

  • web服務器實體bean
class User{
		  	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") // 這裏未指明 傳入字符串的時區
		    private Date date;
}
  • 前臺請求體
{
	"date":"2020-03-07 12:12:12"
}
  • web 服務器 的控制器
@PostMapping("put")
public User put(@RequestBody User user){
	System.out.println(user.getDate()); // Sat Mar 07 20:12:12 CST 2020
}

爲什麼傳入時間是12點,轉成對象就成20點。

源碼註解說了,默認是UTC時間,也就是說,你傳入的12點是0時區的12點,而我web服務器現在在東8區,而東8區,比0時區快8小時,所以轉成對象就成了20點。

指定timezone

修改實體

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

再次測試:

結果:

Sat Mar 07 12:12:12 CST 2020

解釋:

  • 你傳進來的是東8區的CST時間,我web服務器的時區也是東8區。所以結果不需要改變。

正確用法2,輸出

  • web服務器實體bean
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") // 未指定 timezone
    private Date date;
  • web 服務器controller
    @GetMapping("getDate")
    public User getDate(){
        User user = new User();
        Date date = new Date();
        System.out.println(date); // Sat Mar 07 20:45:41 CST 2020
        user.setDate(date);
        return user;
    }
  • 客戶端URL請求獲取的結果
{
    "date": "2020-03-07 12:45:41"
}

解釋:

未指定timezone,也就是說,要輸出的日期字符串的時區是0時區,而現在的web服務器的時區是東8區,new Date()時,就是當前時區的標準時間,0時區比當前web服務器的東8區,慢8小時,所以轉成UTC 的0時區後 的時間就是20-8=12 ,也就是 客戶端URL請求獲取的結果。

timezone = “GMT+8” 就不測了。應該能想明白

總結

  1. timezone 就是假定客戶端在哪個時區。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章