How to Set a Jvm Timezone Properly

How to set a JVM TimeZone Properly

You can pass the JVM this param

-Duser.timezone

For example

-Duser.timezone=Europe/Sofia

and this should do the trick.
Setting the environment variable TZ also does the trick on Linux.

how to set timezone for jvm through command line

See your JVM’s current default time zone by calling ZoneId.systemDefault().

You do not explain what is the default time zone of your host OS (which you have not described) versus that of your Vagrant box. I'm not knowledgeable with running Java containerized but I imagine your Java implementation (which you have not yet described) is picking up its default from either the host OS or the container.

Always specify your desired/expected zone

But here is the thing: You should not care. Your Java programming should never rely implicitly on the JVM’s current default time zone. Your Question itself is evidence for my point.

Instead, always specify a time zone explicitly in your code.

Never rely on default zone

Another reason you should never depend on the default is that it can be changed at any moment during runtime(!) by any code in any thread of any app running within the JVM.

Instead pass your desired/expected time zone as an optional argument.

For example, to get the current moment in a zone:

ZoneId z = ZoneId.of( "America/Adak" );
ZonedDateTime zdt = ZonedDateTime( z );

Look throughout the java.time classes and you'll see that wherever a time zone or offset is relevant you can pass a ZoneId or ZoneOffset object as an optional argument. Personally I believe Java programmers would be better off if those arguments were required rather than optional as so many of us fail to think about the issue of time zone and offset.

changing the JVM timezone in sparklyr

A few things:

  • The name of the property is spark.driver.extraJavaOptions.
  • The value is missing leading -. Should be -Duser.timezone=GMT.
  • For consistency you need both spark.driver.extraJavaOptions and spark.executor.extraJavaOptions.
  • In general case spark.driver.extraJavaOptions and similar properties should be set outside the application. As explained in the official documentation:

    In client mode, this config must not be set through the SparkConf directly in your application, because the driver JVM has already started at that point. Instead, please set this through the --driver-java-options command line option or in your default properties file.

    On the driver calling corresponding Java methods should work

    # sc is spark_shell_connection / spark_connection
    sparklyr::invoke_static(sc, "java.util.TimeZone", "getTimeZone", "GMT") %>%
    sparklyr::invoke_static(sc, "java.util.TimeZone", "setDefault", .)

    but might not be reflected in the UI, and you'll still need spark.executor.extraJavaOptions.

In general case you should edit spark-defualts.conf in the configuration directory to include

spark.driver.extraJavaOptions -Duser.timezone=GMT
spark.executor.extraJavaOptions -Duser.timezone=GMT

If you cannot modify main configuration you can create an application specific directory and point to it using SPARK_CONF_DIR environment variabl.e

In the recent versions you can also set spark.sql.session.timeZone in the application itself (note that it is different than corresponding JVM options and affects only Spark queries).

JVM Timezone is off by one hour

As your first two options - upgrade the JVM and use tzupdater - are not possible, you will have to use a workaround. You can set the default timezone for the JVM using the user.timezone property. You will need to set the timezone to a zone one hour away from the actual timezone to compensate for the 2014 changes.

Russian timezones available are

Europe/Kaliningrad
Europe/Moscow
Europe/Samara
Europe/Volgograd
Asia/Yekaterinburg
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Krasnoyarsk
Asia/Irkutsk
Asia/Yakutsk
Asia/Sakhalin
Asia/Vladivostok
Asia/Anadyr
Asia/Kamchatka
Asia/Magadan

When will a JVM process see the updated time zone from the OS?

When the JVM starts, it loads the default timezone.

  • it can be read from the OS: Windows registry or Linux /etc/localtime (or some other folder, depending on the distribution)
  • it can be read from JVM params/properties: https://stackoverflow.com/a/2493805/7605325
  • in runtime, an application can call TimeZone.setDefault

AFAIK, the third option is the only one that changes the default timezone in runtime. All the others require a JVM restart.

Why is the JVM's default timezone different in these cases

The latest changes related "Turkey switched from EET/EEST (+02/+03) to permanent +03" has not been integrated in JDK8 update 101 which you are using, infact it is not part of latest JDK 8 update 112. You need to manually upgrade the tzupgrader tool to get the changes in your JDK.
Here is the "tzdata2016g" version that has the "Turkey switched from EET/EEST (+02/+03) to permanent +03" integrated, you can find more details here - http://www.oracle.com/technetwork/java/javase/tzdata-versions-138805.html
You need to manually install tzupdator tool that you can get from here - http://www.oracle.com/technetwork/java/javase/tzupdater-readme-136440.html
I hope that solves your problem.



Related Topics



Leave a reply



Submit