I reviewed many questions related to TimeZones on Stackoverflow, but I could not find the one to the problem I am struggling with:
- Why doesn't Joda's
DateTimeZone.getDefault()
return updated timezone on TZ change (after resuming an application?).TimeZone.getDefault()
seems to be working just fine. - Should I use
DateTimeZone.forTimeZone(TimeZone.getDefault())
to get up to date Joda'sDateTimeZone
object?
Here is how to replicate:
- Start app that prints both
DateTimeZone.getDefault()
andTimeZone.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",...]
- Go to settings -> change Timezone to PDT.
- Go back to Application that prints stuff (e.g. in 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",...]
- At this stage I can be rotating the App. The
DateTimeZone.getDefault()
will be stuck. - Only after application onRestart - the value will be correct.
Why is it so?
Joda-Time caches the default timezone.
If you run this code (in my JVM, the default timezone is 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
The output will be:
JVM default=America/Sao_Paulo
Joda Default=America/Sao_Paulo
JVM default=Europe/London
Joda Default=America/Sao_Paulo
true
Also note that t1 == t2
returns true
, which means they are exactly the same instance.
To set Joda's default timezone after changing the JVM default, you must set it in DateTimeZone
too:
// 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
This outputs:
Joda Default=Europe/London
false
After restarting everything, the cache disappears and Joda-Time gets the new default when first called.
You should not directly use Joda-Time but better use the library of Daniel Lew (JodaTimeAndroid - a thin wrapper around Joda-Time) because
- it has better performance characteristics when loading the tz data on Android
- it has a suitable broadcast-receiver to track changes of the system timezone.
来源:https://stackoverflow.com/questions/46243649/why-datetimezone-getdefault-does-not-get-updated-when-zone-in-android-is-chang