我使用spring + hibernate编写了一个webapp。我在Windows上开发了所有内容,然后将其移动到Linux虚拟服务器(Aruba,一家意大利提供商)。我注意到一件令人讨厌的事情:当保存在Windows上的日期与我的“挂钟”相同时,所以如果我读到13:45,我将在mysql行中有相同的小时。无论如何,这在Linux上都不会发生。实际上linux机器也在CEST上(我的时区),我在shell中输入“date”。但我得到了DB中保存的日期,其偏移量相对于GMT。同样,我的应用程序始终以GMT显示所有内容(如果我选择格式化日期以显示时区,则包括GMT作为时区),并且mysql以该格式保存所有内容。我如何控制这一切?
答案 0 :(得分:0)
我自己发布解决方案,因为我认为在这个网站上有它的价值。
首先:mySql不存储任何时区信息。所以说你在GMT + 4上运行并且你写了几个包含日期字段的记录。然后在GMT-2中移动系统,读取这些记录(可能从mysqldump导入数据)。如果您的系统和VM具有GMT-2作为时区,则您阅读的日期将被视为使用GMT-2编写且未调整。
解决方案:使用-Duser.timezone="GMT"
命令行选项控制您的VM时区(您甚至可以将其放入Tomcat启动脚本中)或您首选的时区(但GMT更好,让我解释一下原因)。通过这种方式,您可以确定肯定您的VM正在运行的时区。此并不意味着Java VM将假定您的系统时间是您在user.timezone中指定的时间,它将知道系统时区并相应地调整日期。事实上,如果您不在GMT中,您将看到日期调整为GMT并相应地保存到DB。这样您就可以确定使用它作为参考。
问题在于,如果您选择日期对象并执行myDateObject.toString()
,则会将日期调整为GMT,小时偏移量。这不是你可能想要的。
解决方案是使用SimpleDateFormat
,并在必须输出日期时做这样的事情:
SimpleDateFormat dateFormat = new SimpleDateFormat(
"HH:mm dd/MM/yyyy z", Locale.ITALY);
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Rome"));
一切都会以正确的方式转换。如果您正在开发Web应用程序,甚至可以更进一步。您可以从HttpRequest中提取时区并相应地调整日期输出,但我没有做到这么远,因为我正在编写仅供意大利用户使用的应用程序:D(yay)。
希望这会有所帮助。