I have a Linux box running a Docker container, which is running TomEE, and running a WAR I built.
On the base Linux box, I get a "date" value of "Fri Jan 20 10:37:27 PST 2017". The TZ environment variable is not set.
When I run the following class:
import java.util.Date;
import java.util.TimeZone;
public class DatePrint {
public static void main(String[] args) {
System.out.println("date[" + new Date() + "] tzoffset[" + TimeZone.getDefault().getOffset(new java.util.Date().getTime()) + "]");
}
}
I get this:
date[Fri Jan 20 10:39:02 PST 2017] tzoffset[-28800000]
This is all fine.
In my Docker container running on the box, where I have "-v /etc/localtime:/etc/localtime" as one of the volume mappings, I obviously have the same /etc/localtime file. The TZ environment variable is not set. When I run "date" inside the container, I get a time value in the same timezone (PST) as in the base host.
I then compile and run the same Java class as above, and I get the following:
date[Fri Jan 20 18:30:38 UTC 2017] tzoffset[0]
I then manually set the TZ environment variable in the container (remember that it's not set in the base host) to "America/Los_Angeles" (I verified this value by looking at the file that "/etc/localtime" symlinks to on the base host).
I then reran the class on the container and got this:
date[Fri Jan 20 10:35:08 PST 2017] tzoffset[-28800000]
Note that the two versions of Java on the base host and the container are almost identical. They are both OpenJDK 1.8.0_111 (b15 on the host, b14 on the container).
So, can someone explain what's going on here? On the base host, I had "etc/localtime" pointing to the proper file, but I did not have TZ set. It reports the correct timezone with "date" and in the Java class. On the container, "/etc/localtime" is pointing to the proper file, and I didn't originally have TZ set. The "date" command returns the correct value, but Java did not.
I had to manually set TZ on the container to the TZ value from the host, and that made it work. I'd really rather not do this. That seems like a hack to me.
Update:
I noticed the following in the "localtime(5)" man page:
Because the timezone identifier is extracted from the symlink target name of /etc/localtime, this file may not be a normal file or hardlink.
So, that may be part of my problem. It's still curious that "date" from the shell works fine, but Java (without the TZ setting) gets confused.
i had the same issue as you (CentOS, Docker, OpenJDK). We solved it this way:
Don't mount localtime, mount /etc/timezone.
If you don't have a /etc/timezone file (e.g. on CentOS), you can do something like this (on the host):
timedatectl | awk '/Time zone:/ {print $3}' > /etc/timezone_host
Then in the container (e.g. entry point)
TZ_HOST=$(cat /etc/timezone_host)
echo $TZ_HOST > /etc/timezone
export TZ=$TZ_HOST
dpkg-reconfigure --frontend noninteractive tzdata
Follow Gilles's answer in https://unix.stackexchange.com/questions/452559/what-is-etc-timezone-used-for, Java reads /etc/timezone instead of /etc/localtime because of historical reasons. Further explanations can be found in that post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With