Java 时区乱了
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Time Zone is messed up
提问by Mike Stone
I am running a Tomcat application, and I need to display some time values. Unfortunately, the time is coming up an hour off. I looked into it and discovered that my default TimeZone is being set to:
我正在运行一个 Tomcat 应用程序,我需要显示一些时间值。不幸的是,时间快到一个小时了。我查看了它,发现我的默认时区被设置为:
sun.util.calendar.ZoneInfo[id="GMT-08:00",
offset=-28800000,
dstSavings=0,
useDaylight=false,
transitions=0,
lastRule=null]
Rather than the Pacific time zone. This is further indicated when I try to print the default time zone's display name, and it comes up "GMT-08:00", which seems to indicate to me that it is not correctly set to the US Pacific time zone. I am running on Ubuntu Hardy Heron, upgraded from Gutsy Gibbon.
而不是太平洋时区。当我尝试打印默认时区的显示名称时会进一步指出这一点,并且出现“GMT-08:00”,这似乎表明它没有正确设置为美国太平洋时区。我在 Ubuntu Hardy Heron 上运行,从 Gutsy Gibbon 升级。
Is there a configuration file I can update to tell the JRE to use Pacific with all the associated daylight savings time information? The time on my machine shows correctly, so it doesn't seem to be an OS-wide misconfiguration.
是否有我可以更新的配置文件来告诉 JRE 将 Pacific 与所有相关的夏令时信息一起使用?我机器上的时间显示正确,所以它似乎不是操作系统范围的错误配置。
Ok, here's an update. A coworker suggested I update JAVA_OPTS in my /etc/profile to include "-Duser.timezone=US/Pacific", which worked (I also saw CATALINA_OPTS, which I updated as well). Actually, I just exported the change into the variables rather than use the new /etc/profile (a reboot later will pick up the changes and I will be golden).
好的,这里有一个更新。一位同事建议我在我的 /etc/profile 中更新 JAVA_OPTS 以包含“-Duser.timezone=US/Pacific”,这有效(我也看到了 CATALINA_OPTS,我也更新了)。实际上,我只是将更改导出到变量中,而不是使用新的 /etc/profile(稍后重新启动将获取更改,我将获得成功)。
However, I still think there is a better solution... there should be a configuration for Java somewhere that says what timezone it is using, or how it is grabbing the timezone. If someone knows such a setting, that would be awesome, but for now this is a decent workaround.
但是,我仍然认为有一个更好的解决方案......应该在某处有一个 Java 配置,说明它正在使用什么时区,或者它是如何获取时区的。如果有人知道这样的设置,那就太棒了,但现在这是一个不错的解决方法。
I am using 1.5, and it is most definitely a DST problem. As you can see, the time zone is set to not use daylight savings. My belief is it is generically set to -8 offset rather than the specific Pacific timezone. Since the generic -8 offset has no daylight savings info, it's of course not using it, but the question is, where do I tell Java to use Pacific time zone when it starts up? I'm NOT looking for a programmatic solution, it should be a configuration solution.
我使用的是 1.5,这绝对是一个 DST 问题。如您所见,时区设置为不使用夏令时。我的信念是它通常设置为 -8 偏移而不是特定的太平洋时区。由于通用 -8 偏移量没有夏令时信息,它当然没有使用它,但问题是,我在哪里告诉 Java 在启动时使用太平洋时区?我不是在寻找程序化解决方案,它应该是一个配置解决方案。
采纳答案by Jason Day
It's a "quirk" in the way the JVM looks up the zoneinfo file. See Bug ID 6456628.
这是 JVM 查找 zoneinfo 文件方式的一个“怪癖”。请参阅错误 ID 6456628。
The easiest workaround is to make /etc/localtime a symlink to the correct zoneinfo file. For Pacific time, the following commands should work:
最简单的解决方法是使 /etc/localtime 成为指向正确 zoneinfo 文件的符号链接。对于太平洋时间,以下命令应该可以工作:
# sudo cp /etc/localtime /etc/localtime.dist
# sudo ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
I haven't had any problems with the symlink approach.
我对符号链接方法没有任何问题。
Edit: Added "sudo" to the commands.
编辑:在命令中添加了“sudo”。
回答by McDowell
It may help to double-check the timezone rules your OS is using.
仔细检查您的操作系统正在使用的时区规则可能会有所帮助。
/usr/bin/zdump -v /etc/localtime | less
This file should contain your daylight savings rules, like this one for the year 2080:
此文件应包含您的夏令时规则,例如 2080 年的规则:
/etc/localtime Sun Mar 31 01:00:00 2080 UTC = Sun Mar 31 02:00:00 2080 BST isdst=1 gmtoff=3600
You can compare this with the timezone rules you think you should be using. They can be found in /usr/share/zoneinfo/.
您可以将其与您认为应该使用的时区规则进行比较。它们可以在/usr/share/zoneinfo/ 中找到。
回答by abarax
I had a similar issue, possibly the same one. However my tomcat server runs on a windows box so the symlink solution will not work.
我有一个类似的问题,可能是同一个问题。但是,我的 tomcat 服务器运行在 Windows 机器上,因此符号链接解决方案将不起作用。
I set -Duser.timezone=Australia/Sydney
in the JAVA_OPTS
however tomcat would not recognize that DST was in effect. As a workaround I changed Australia/Sydney
(GMT+10:00) to Pacific/Numea
(GMT+11:00) so that times would correctly display however I would love to know the actual solution or bug, if any.
我设置-Duser.timezone=Australia/Sydney
了JAVA_OPTS
但是 tomcat 不会识别 DST 生效。作为一种解决方法,我将Australia/Sydney
(GMT+10:00) 更改为Pacific/Numea
(GMT+11:00) 以便正确显示时间,但是我很想知道实际的解决方案或错误(如果有)。
回答by Liu Zehua
On Ubuntu, it's not enough to just change the /etc/localtime file. It seems to read /etc/timezone file, too. It's better follow the instructionto set the time zone properly. In particular, do the following:
在 Ubuntu 上,仅更改 /etc/localtime 文件是不够的。它似乎也读取 /etc/timezone 文件。最好按照说明正确设置时区。特别是,请执行以下操作:
$ sudo cp /etc/timezone /etc/timezone.dist
$ echo "Australia/Adelaide" | sudo tee /etc/timezone
Australia/Adelaide
$ sudo dpkg-reconfigure --frontend noninteractive tzdata
Current default time zone: 'Australia/Adelaide'
Local time is now: Sat May 8 21:19:24 CST 2010.
Universal Time is now: Sat May 8 11:49:24 UTC 2010.
On my Ubuntu, if /etc/localtime and /etc/timezone are inconsistent, Java seems to read default time zone from /etc/timezone .
在我的 Ubuntu 上,如果 /etc/localtime 和 /etc/timezone 不一致,Java 似乎从 /etc/timezone 读取默认时区。