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

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

  • 为什么Joda的DateTimeZone.getDefault()在TZ更改时没有返回更新的时区(恢复应用程序后?)。 TimeZone.getDefault()似乎工作正常
  • 我应该使用DateTimeZone.forTimeZone(TimeZone.getDefault())来获取最新的Joda的DateTimeZone对象吗?

以下是如何复制:

  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. 在这个阶段,我可以旋转App。 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默认= America / Sao_Paulo
Joda默认= America / Sao_Paulo
JVM默认=欧洲/伦敦
Joda默认= America / Sao_Paulo
真正

另请注意, t1 == t2返回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默认=欧洲/伦敦

重新启动所有内容后,缓存消失,Joda-Time在首次调用时获取新的默认值。

你不应该直接使用Joda-Time,而是更好地使用Daniel Lew的库 ( JodaTimeAndroid – Joda-Time的薄包装),因为

  • 在Android上加载tz数据时,它具有更好的性能特征
  • 它有一个合适的广播接收器来跟踪系统时区的变化。