一、問題由來
前一天下午正在寫程式碼的時候,領導突然走過來跟我說,讓我去看一個神祕的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終於解決。