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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值