为什么 DateTimeZone.getDefault() 在 Android 中的区域更改时不会更新
Why DateTimeZone.getDefault() does not get updated when Zone in Android is changed
我在 Whosebug 上查看了许多与 TimeZones 相关的问题,但我找不到解决我正在努力解决的问题的问题:
- 为什么 Joda 的
DateTimeZone.getDefault()
return 更新了 TZ 时区(在恢复应用程序后?)。 TimeZone.getDefault()
似乎工作正常.
- 我应该使用
DateTimeZone.forTimeZone(TimeZone.getDefault())
来更新 Joda 的 DateTimeZone
对象吗?
复制方法如下:
- 启动同时打印
DateTimeZone.getDefault()
和 TimeZone.getDefault()
的应用程序:
09-15 16:46:59.512 14961-14961/com.example.android.whatever D/TimeZone:
DateTimeZone.getDefault()=Europe/London; TimeZone.getDefault()=libcore.util.ZoneInfo[id="Europe/London",...]
- 转到设置 -> 将时区更改为 PDT。
- 返回打印内容的应用程序(例如在 onResume() 中):
09-15 08:49:24.727 14961-14961/com.example.android.whatever
D/TimeZone: DateTimeZone.getDefault()=Europe/London;
TimeZone.getDefault()libcore.util.ZoneInfo[id="America/Los_Angeles",...]
- 在这个阶段我可以轮换应用程序。
DateTimeZone.getDefault()
会卡住。
- 只有在应用 onRestart 后 - 值才会正确。
为什么会这样?
Joda-Time 缓存默认时区。
如果你运行这段代码(在我的JVM中,默认时区是America/Sao_Paulo
):
System.out.println("JVM default=" + TimeZone.getDefault().getID()); // America/Sao_Paulo
DateTimeZone t1 = DateTimeZone.getDefault();
System.out.println("Joda Default=" + t1); // America/Sao_Paulo
// setting the default timezone to London
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
System.out.println("JVM default=" + TimeZone.getDefault().getID()); // Europe/London
DateTimeZone t2 = DateTimeZone.getDefault();
System.out.println("Joda Default=" + t2); // America/Sao_Paulo
System.out.println(t1 == t2); // true
输出将是:
JVM default=America/Sao_Paulo
Joda Default=America/Sao_Paulo
JVM default=Europe/London
Joda Default=America/Sao_Paulo
true
还要注意 t1 == t2
returns true
,这意味着它们是完全相同的实例。
要在更改 JVM 默认值后设置 Joda 的默认时区,您也必须在 DateTimeZone
中设置它:
// change Joda's default timezone to be the same as the JVM's
DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault()));
DateTimeZone t3 = DateTimeZone.getDefault();
System.out.println("Joda Default=" + t3); // Europe/London
System.out.println(t1 == t3); // false
这输出:
Joda Default=Europe/London
false
重启一切后,缓存消失,Joda-Time 在首次调用时获得新的默认值。
您不应直接使用 Joda-Time,但最好使用 Daniel Lew 的库(JodaTimeAndroid - Joda-Time 的精简包装)因为
- 在 Android
上加载 tz 数据时具有更好的性能特征
- 它有一个合适的广播接收器来跟踪 system timezone 的变化。
我在 Whosebug 上查看了许多与 TimeZones 相关的问题,但我找不到解决我正在努力解决的问题的问题:
- 为什么 Joda 的
DateTimeZone.getDefault()
return 更新了 TZ 时区(在恢复应用程序后?)。TimeZone.getDefault()
似乎工作正常. - 我应该使用
DateTimeZone.forTimeZone(TimeZone.getDefault())
来更新 Joda 的DateTimeZone
对象吗?
复制方法如下:
- 启动同时打印
DateTimeZone.getDefault()
和TimeZone.getDefault()
的应用程序:
09-15 16:46:59.512 14961-14961/com.example.android.whatever D/TimeZone: DateTimeZone.getDefault()=Europe/London; TimeZone.getDefault()=libcore.util.ZoneInfo[id="Europe/London",...]
- 转到设置 -> 将时区更改为 PDT。
- 返回打印内容的应用程序(例如在 onResume() 中):
09-15 08:49:24.727 14961-14961/com.example.android.whatever D/TimeZone: DateTimeZone.getDefault()=Europe/London; TimeZone.getDefault()libcore.util.ZoneInfo[id="America/Los_Angeles",...]
- 在这个阶段我可以轮换应用程序。
DateTimeZone.getDefault()
会卡住。 - 只有在应用 onRestart 后 - 值才会正确。
为什么会这样?
Joda-Time 缓存默认时区。
如果你运行这段代码(在我的JVM中,默认时区是America/Sao_Paulo
):
System.out.println("JVM default=" + TimeZone.getDefault().getID()); // America/Sao_Paulo
DateTimeZone t1 = DateTimeZone.getDefault();
System.out.println("Joda Default=" + t1); // America/Sao_Paulo
// setting the default timezone to London
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
System.out.println("JVM default=" + TimeZone.getDefault().getID()); // Europe/London
DateTimeZone t2 = DateTimeZone.getDefault();
System.out.println("Joda Default=" + t2); // America/Sao_Paulo
System.out.println(t1 == t2); // true
输出将是:
JVM default=America/Sao_Paulo
Joda Default=America/Sao_Paulo
JVM default=Europe/London
Joda Default=America/Sao_Paulo
true
还要注意 t1 == t2
returns true
,这意味着它们是完全相同的实例。
要在更改 JVM 默认值后设置 Joda 的默认时区,您也必须在 DateTimeZone
中设置它:
// change Joda's default timezone to be the same as the JVM's
DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault()));
DateTimeZone t3 = DateTimeZone.getDefault();
System.out.println("Joda Default=" + t3); // Europe/London
System.out.println(t1 == t3); // false
这输出:
Joda Default=Europe/London
false
重启一切后,缓存消失,Joda-Time 在首次调用时获得新的默认值。
您不应直接使用 Joda-Time,但最好使用 Daniel Lew 的库(JodaTimeAndroid - Joda-Time 的精简包装)因为
- 在 Android 上加载 tz 数据时具有更好的性能特征
- 它有一个合适的广播接收器来跟踪 system timezone 的变化。