Java 有时区的奇怪的mysql生物?如何控制它们?

Java 有时区的奇怪的mysql生物?如何控制它们?,java,timezone,Java,Timezone,我用spring+hibernate编写了一个webapp。我在windows上开发了所有东西,然后将其移动到Linux虚拟服务器(Aruba,意大利提供商)。我注意到一件恼人的事情:当日期保存在windows上时,时间将与我的“挂钟”相同,因此如果我阅读13:45,mysql行中的时间将相同。无论如何,这在Linux上不会发生。事实上,linux机器也在CEST上(我的时区),我让它在shell中键入“date”。但我在数据库中保存的日期的偏移量是相对于GMT的。同样,我的应用程序总是以GMT

我用spring+hibernate编写了一个webapp。我在windows上开发了所有东西,然后将其移动到Linux虚拟服务器(Aruba,意大利提供商)。我注意到一件恼人的事情:当日期保存在windows上时,时间将与我的“挂钟”相同,因此如果我阅读13:45,mysql行中的时间将相同。无论如何,这在Linux上不会发生。事实上,linux机器也在CEST上(我的时区),我让它在shell中键入“date”。但我在数据库中保存的日期的偏移量是相对于GMT的。同样,我的应用程序总是以GMT显示所有内容(如果我选择格式化日期以显示时区,则将GMT作为时区显示),mysql则以该格式保存所有内容。我如何控制这一切?

我自己发布解决方案,因为我认为它值得在这个网站上使用

首先:mySql不存储任何时区信息。假设您运行的是GMT+4,您编写了两条包含日期字段的记录。然后在GMT-2中移动系统,读取这些记录(可能从mysqldump导入数据)。如果您的系统和虚拟机将GMT-2作为时区,则您读取的日期将被视为是用GMT-2编写的,并且不会进行调整

解决方案:通过使用
-Duser.timezone=“GMT”
命令行选项(您甚至可以将其放在Tomcat启动脚本中)或您喜欢的时区(但GMT更好,让我解释一下原因),控制您的VM时区。这样,您就可以肯定地知道您的虚拟机正在运行哪个时区。这并不意味着Java VM将假定您的系统时间是您在用户中指定的时间。时区,它将知道系统时区并相应地调整日期。事实上,如果您不在GMT中,您将看到中的日期调整为GMT并相应地保存到DB。通过这种方式,您将确保将其用作参考

问题是,如果您使用date对象并执行
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)

希望这会有所帮助