做開發需要注意的Java日期格式化的細節

公司項目登錄模塊中有一個參數,需要使用日期(年月日時)來計算出一個校驗碼,時間上沒有用分和秒,因爲手機上的時間和服務器上的時間沒法完全同步嘛。點擊登錄時傳給後臺,後臺也會使用日期(年月日時),以相同的算法計算校驗碼,然後和接收到的參數做比較,如果不相同,則不讓登錄。

有一天,我發現App登錄失敗了,最後發現問題的原因是Android手機的時區選了一個國外的,與中國的標準時區相差4個小時,比如現在中國是1點整,則手機app的時間則是5點整,我們拿5點整這個時間來計算校驗碼,而服務器拿1點整這個時間來計算校驗碼,計算出來的校驗碼肯定是不相同的。

瞭解了問題的原因,接下來想解決方案,剛開始和大家的想法是一致,把手機時區調好就行了,但是這樣的話兼容性太差了,萬一你的用戶就是外國人呢,它在國外,手機使用國外的時區很正常啊,對於他來說,他的時間是正確的呀,你讓他去把時區調成中國的,不太現實吧!

想到這裏,我就產生了一個問題,假設在同一時刻,在美國的計算機調用System.currentMillis()和在中國的計算機調用System.currentMillis()拿到的時間毫秒值是否是一樣的呢?經過百度,是一樣的,於是解決方案就出來了,我們在格式化時間的時候就指定爲中國時區,既然服務器使用的是中國的時區格式化的(默認不指定時區則使用的是計算機默認的時區,中國的計算機默認時區一般都是中國),所以在手機上,只要時間是正確的,我不管用戶設置了什麼時區,我格式化時間的時候指定爲中國的時區來格式化就可以和服務器保持一致,實現代碼如下:

val simpleDateFormat = SimpleDateFormat("yyyyMMddHH", Locale.CHINA)

以爲這樣就OK了,結果運行時間還是不對,經過百度找到了答案,其實上面的Local.CHINA並沒有指定時區,要指定時區,代碼如下:

val simpleDateFormat = SimpleDateFormat("yyyyMMddHH", Locale.CHINA)
simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Shanghai")

Ok,這樣才指定了時區,中國的時區使用的是上海,不是我們想象的北京,Asia表示亞洲。指定了時區之後,如果計算出來的校驗碼不對,則能肯定是因爲手機時間不對(排除服務器時間不對,一般服務器時間不會有問題的),如果用戶說手機時間是對的呀,那你就知道是用戶的手機時區不對了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章