platform
RK3288 + Android 7.1
problem
修改系统时区后, 使用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);
}
Test steps:
- Enter test Activity
- Press HOME to return to Launcher
- Open Settings -> Time and Date
- Turn off automatic date and time confirmation, and turn off automatic time zone determination.
- Choose a time zone different from the current one.
- Return to test Activity.
During this process, onResume will be executed twice. Assuming that it takes 1 minute in total from 2->6, the time zone is switched from GMT+8 to GMT+1:
The first output time is:
2019-07-17 08:00 :00
The second output time is:
Expected: 2019-07-17 01:01:00
Actual: 2019-07-17 08:01:00
Analysis and solutions
After testing, it was found that the reason is that the time zone in SimpleDateFormat did not change with the actual time zone change:
final String DatePattern = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(DatePattern, Locale.getDefault());
The solution is to recreate SimpleDateFormat after the time zone changes.
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);
}
Expand
In Android, you can trigger the update of the relevant code by registering the time zone change broadcast, reference:
|-- 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);