查詢時間倒退一天-專案中驚現神祕BUG-JsonFormat使用採坑記

一隻愛閱讀的程式設計師發表於2020-12-09

一、問題由來

前一天下午正在寫程式碼的時候,領導突然走過來跟我說,讓我去看一個神祕的BUG,說是在資料庫中查詢時的一個日期

返回到頁面後,查詢時間倒退了一天。一聽到這個BUG,我就感覺很奇怪,還有這樣的BUG?也讓我滿是期待,究竟是

什麼樣的BUG會導致這個問題呢?


二、問題分析

 這就是一個很簡單的列表查詢,查詢條件都只有一個怎麼出現這麼奇怪的BUG呢?我立馬在本地測試了一下,結果還真是時間向前

倒退了一天。這個是查詢的結果,

 

這個是使用Swagger測試的結果,

 

 以0002這家企業為例,資料庫查詢的tableDate為2020-09-01,可是返回到頁面中時卻是2020-08-31,日期確實向前減了一天。

看到這個測試結果讓我很驚訝,還真神了。這是時間發生錯亂了嘛,還是發生時空穿梭了,問題竟然還真出現了。我去看了另外

一個查詢,只查詢年份的一個介面,結果更神奇,年份的查詢結果為1970年。資料庫查詢結果如下,

 

 頁面中返回的結果為,

 

 自己看到這結果都不得不相信這個現實。接著開始排查原因,查詢年份的資料在返回頁面前列印的資料為,

 

 從列印的結果來看是正確的,沒什麼異常。可是檢視第一個查詢最後返回的資料時,發現有不對勁的地方,最後返回的是時間戳,而不是字串的日期。

 

 我將時間戳轉換為日期後發現也是正確的,

 

 

 接著進一步排查,看看這兩個輸出類中對應的日期欄位是什麼,

 

 

 

 

 這兩個返回的輸出類中,日期欄位都使用了java中的Date型別,並且使用了一個註解JsonFormat註解。這個註解是同事推介使用的,

使用這個註解的好處是,不需要在查詢的SQL中對查詢結果有日期、時間的欄位做格式化處理,格式化日期和時間的操作全部放在Java

的輸出類中來進行處理。這樣對於我們開發來說,改動的程式碼量會小很多,不然不同的資料庫比如Mysql和Oracle就需要使用不同的語法

進行格式化。對於開發來說,有複雜和簡單的兩種方法來解決問題,如果有得選,那麼我一定會選擇簡單的辦法來處理問題。

自己嘗試使用各種辦法,比如格式化日期時使用年月日時分秒,沒有解決;輸出類中使用字串來接收查詢的日期型別,可以解決。

到此可以確定一點就是格式化這裡出問題了。


三、解決方案

和同事說了這個問題後,同事幫忙查詢原因,最終找到一篇文章,找到了這個問題的解決辦法。https://blog.csdn.net/a992795427/article/details/87094200

問題的原因是在使用JsonFormat這個註解時,使用的時區不一樣,預設使用的是標準的格林威治時間,而我們中國所在的時區為東八區,需要在預設

時區上面加8個小時,記得這好像是初中的地理常識。在配置檔案中新增上這一行配置之後,

spring.jackson.time-zone=GMT+8

問題解決。另外一個問題,只查詢年份的時候,年份變為1970年的原因是使用JsonFormat註解格式化日期時,不能直接格式化為年份。這是通過實踐

得出的經驗。至此神祕BUG終於解決。

 

相關文章