Android 修改系統時區導致SimpleDateFormat無法輸出正確時間

平臺

RK3288 + Android 7.1

問題

修改系統時區後, 使用SimpleDateFormat 無法轉化出正確的時間.
    final String DatePattern = "yyyy-MM-dd HH:mm:ss";
    SimpleDateFormat sdf = new SimpleDateFormat(DatePattern, Locale.getDefault());
    @Override
    protected void onResume() {
        super.onResume();

        Date date = new Date();
        android.util.Log.d("DateTest", sdf.format(date);
    }

測試步驟:

  1. 進入測試Activity
  2. 按HOME鍵返回Launcher
  3. 打開設置->時間和日期
  4. 關閉自動確認日期和時間, 關閉自動確定時區.
  5. 選擇一個與當前不同的時區.
  6. 返回測試Activity.

在這個過程中, onResume會執行兩次, 假設在2->6總共花費了1分鐘, 時區由 GMT+8 切換爲 GMT+1 :
第一次輸出的時間爲:
2019-07-17 08:00:00

第二次輸出的時間爲:
預期: 2019-07-17 01:01:00
實際: 2019-07-17 08:01:00

分析與解決方案

測試後發現, 原因在於SimpleDateFormat中的時區並沒有跟隨實際時區變化而改變:

    final String DatePattern = "yyyy-MM-dd HH:mm:ss";
    SimpleDateFormat sdf = new SimpleDateFormat(DatePattern, Locale.getDefault());

解決的方法是在時區變化後, 重新創建SimpleDateFormat.

    final String DatePattern = "yyyy-MM-dd HH:mm:ss";
    SimpleDateFormat sdf = new SimpleDateFormat(DatePattern, Locale.getDefault());
    @Override
    protected void onResume() {
        super.onResume();
		sdf = new SimpleDateFormat(DatePattern, Locale.getDefault());
        Date date = new Date();
        android.util.Log.d("DateTest", sdf.format(date);
    }

擴展

在Android中, 可以通過註冊時區變化廣播來觸發更新相關代碼, 參考:
|-- frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_TICK);
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
        getContext().registerReceiver(mIntentReceiver, filter, null, null);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章