Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between System.setProperty("user.timezone", "America/Chicago"); and TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));

Tags:

java

timezone

  1. System.setProperty("user.timezone", "America/Chicago");
  2. TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));

What is the difference between the two? Which one is better/recommended for setting the timezone?

like image 537
user1006375 Avatar asked Aug 10 '12 18:08

user1006375


2 Answers

Looking at the code, the difference is essentially about when the TimeZone default gets set -

In the first case the default takes effect when the first call to TimeZone class is made(essentially lazily) - say TimeZone.getDefault() , at this point the TimeZone.setDefault gets called, the user.timezone is looked up and the default is set.

In the second scenario, the default is set eagerly - when you explicitly call TimeZone.setDefault

I think that is the only difference, either one should in practice work fine.

Update This is the code from java.util.TimeZone class

The very first call to TimeZone.getDefault() has this flow, which covers your first point.

TimeZone.getDefault()
    -> TimeZone.setDefaultZone() (lookup "user.timezone" , set class variable and return timezone)
          -> return defaulttimezone

Next time getDefault() is called, it just returns the class variable

In the case of TimeZone.setDefault(timeZone), the class level variable defaultTimeZone is being set: defaultTimeZone = zone; and returned.

like image 58
Biju Kunjummen Avatar answered Nov 06 '22 08:11

Biju Kunjummen


The biggest difference should be that "user.timezone" property and TimeZone's default timezone are stored separately.

See Java SE 8 doc TimeZone#getDefault, TimeZone#setDefault.

The main point is that TimeZone.getDefault may use "user.timezone" property as it's initial value, but the value will be cached. That means following changes to "user.timezone" won't affect TimeZone.getDefault. And TimeZone.setDefault does not change "user.timezone" property.

If you are not sure which one your code or third party libraries depend on, you'd better set both:

System.setProperty("user.timezone", "America/Chicago");
TimeZone.setDefault(null); // or TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));

Take Joda Time as an example, it depends on both "user.timezone" property and TimeZone.getDefault, and "user.timezone" take precedence. See DateTiimeZone.getDefault:

try {
    String id = System.getProperty("user.timezone");
    if (id != null) {  // null check avoids stack overflow
        zone = forID(id);
    }
} catch (RuntimeException ex) {
    // ignored
}
if (zone == null) {
    zone = forTimeZone(TimeZone.getDefault());
}
like image 1
Bian Jiaping Avatar answered Nov 06 '22 08:11

Bian Jiaping