为什么 DateTimeZone.getDefault() 在 Android 中的区域更改时不会更新

Why DateTimeZone.getDefault() does not get updated when Zone in Android is changed

我在 Whosebug 上查看了许多与 TimeZones 相关的问题,但我找不到解决我正在努力解决的问题的问题:

复制方法如下:

  1. 启动同时打印 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",...]

  1. 转到设置 -> 将时区更改为 PDT。
  2. 返回打印内容的应用程序(例如在 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",...]

  1. 在这个阶段我可以轮换应用程序。 DateTimeZone.getDefault()会卡住。
  2. 只有在应用 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 的变化。