有一需求,項目中在顯示的日期後面需要額外顯示一下是周幾。這個時候SimpleDateFormat("E")就派上用場了,畢竟SimpleDateFormat("E")在很多人看來可以完美獲取到中國人喜愛的星期幾。
功能刷刷的完成了,順利的通過本地測試,測試環境測試,沒問題後,生產環境灰度測試。嗚,,,嗚,,,嗚,,,翻車了。
原因:
經過一番查看,發現使用SimpleDateFormat("E")格式化的星期變成英文的了,不再上熟悉的中文。這和事先說好的不一樣啊。經過驗證,最終得出java虛擬機讀取時區不同的原因。
爲了驗證這個結論,在出現問題的服務器上輸出了
System.out.println("獲得時區:" + Locale.getDefault());
輸出的結果:獲得時區:en_US
出現問題的原因:
出現這種問題的原因有以下幾點:
1 啓動虛擬機時指定了時區
2 系統的時區不對
2 指定了錯誤的時區。
解決辦法:
解決辦法:SimpleDateFormat("E", Locale.CHINA);
在構造方法中顯示指定時區。
主要的源碼分析和注意事項:
1: 如下圖所示,使用錯誤的SimpleDateFormat("E")進行操作時,調用了SimpleDateFormat(String pattern, Locale locale)構造方法。對於第二個參數,jvm在啓動的時候會讀取默認的時區。
第二張圖是獲取默認時區的方法,格式化時間會走第二個case,但是圖中畫圈的initDefault(category)方法只會在jvm啓動的時候運行,以後調用就不需要再走了。
注意:
1:SimpleDateFormat("E"),這個構造方法雖然會默認獲取時區,但是並不保證獲取成功,因爲這個方法可能不支持所有的地方。所以,對於想要覆蓋全部的地區,java建議使用DateFormat類。
2: 由於時區的獲取是jvm啓動的時候獲取到的。如果在運行過程中比如說修改了服務器的時區,jvm是無法感知的。
總結:
java源碼中已經寫的相當清楚,多看源碼,多學習。