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
andspark.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
Installing Oracle Jdk on Windows Subsystem for Linux
Linux Command for Extracting War File
How to Debug Java -Jni Using Gdb on Linux
How to Get Rjava 0.9-3 to Work on Os X 10.7.4 with Oracle Java 1.7
Access Restriction: the Type 'Application' Is Not API (Restriction on Required Library Rt.Jar)
Convert Character to Ascii Numeric Value in Java
Converting a Date String to a Datetime Object Using Joda Time Library
JPA Cascadetype.All Does Not Delete Orphans
How to Convert a JSON String to a Map<String, String> with Jackson JSON
Differences Between System.Out.Println() and Return in Java
Java.Lang.Classnotfoundexception in Spite of Using Classpath Environment Variable
What Is the Purpose of Java's Unary Plus Operator
Getting Fonts, Sizes, Bold,...Etc
Why Does Priorityqueue.Tostring Return the Wrong Element Order
Spring @Transactional - Isolation, Propagation