我有一个运行 Docker 容器的 Linux 机器,它运行 TomEE,并运行我构建的 WAR。
在基本 Linux 机器上,我得到“日期”值“2017 年 1 月 20 日星期五 10:37:27 PST”。未设置 TZ 环境变量。
当我运行以下类时:
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()) + "]");
}
}
我明白了:
date[Fri Jan 20 10:39:02 PST 2017] tzoffset[-28800000]
这一切都很好。
在盒子上运行的 Docker 容器中,我将“-v/etc/localtime:/etc/localtime”作为卷映射之一,显然我有相同的/etc/localtime 文件。未设置 TZ 环境变量。当我在容器内运行“date”时,我得到了与基本主机相同时区 (PST) 的时间值。
然后我编译并运行与上面相同的 Java 类,我得到以下内容:
date[Fri Jan 20 18:30:38 UTC 2017] tzoffset[0]
然后我手动将容器中的 TZ 环境变量(记住它没有在基本主机中设置)设置为“America/Los_Angeles”(我通过查看“/etc/localtime”符号链接(symbolic link)到的文件验证了这个值在基础主机上)。
然后我在容器上重新运行类并得到这个:
date[Fri Jan 20 10:35:08 PST 2017] tzoffset[-28800000]
请注意,基础主机和容器上的两个 Java 版本几乎相同。它们都是 OpenJDK 1.8.0_111(主机上为 b15,容器上为 b14)。
那么,有人可以解释一下这里发生了什么吗?在基本主机上,我有指向正确文件的“etc/localtime”,但我没有设置 TZ。它使用“日期”和 Java 类报告正确的时区。在容器上,“/etc/localtime”指向正确的文件,我最初没有设置 TZ。 “日期”命令返回正确的值,但 Java 没有。
我必须手动将容器上的 TZ 设置为来自主机的 TZ 值,这才成功。我真的宁愿不这样做。这对我来说似乎是一个 hack。
更新:
我在“localtime(5)”手册页中注意到以下内容:
Because the timezone identifier is extracted from the symlink target name of /etc/localtime, this file may not be a normal file or hardlink.
所以,这可能是我的问题的一部分。仍然很好奇 shell 中的“date”工作正常,但 Java(没有 TZ 设置)会感到困惑。
最佳答案
关注 Gilles 在 https://unix.stackexchange.com/questions/452559/what-is-etc-timezone-used-for 中的回答,由于历史原因,Java读取/etc/timezone
而不是/etc/localtime
。可以在该帖子中找到进一步的解释。
关于java - Docker 容器中的 OpenJDK 1.8.0 与/etc/timezone 和主机的时区不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41770464/