JDBC + MySQL可以被说服忽略时区吗?

我有一个Java Web应用程序,其中客户端将带时间戳的数据发送到服务器以存储在MySQL数据库中并在以后检索。 这些时间戳应始终视为本地时间,并且永远不会根据时区进行调整:如果一个时区中的客户端输入的时间为18:00:00,则应在另一个时区显示为18:00:00的客户端。

保存此值的数据库列的类型为DATETIME,因为我认为它没有时区调整。 java应用程序接收时间戳作为java.util.Date对象,并在将它们插入PreparedStatements之前将它们转换为java.sql.Timestamp对象。 但是,在此过程中的某个位置,当客户端和服务器位于不同的时区时,时间值会偏移。

为了让你了解我正在寻找什么,我可以将所有时间戳存储为字符串,这正是我想要的效果,但是我必须将字符串格式化并解析为日期时才有意义。他们需要被操作。

当时间戳值应始终被视为本地时间时,处理此类应用程序的常用方法是什么?

问题是java.util.Date表示“时间点”而不是像18:00这样的时间。 (在这种情况下,时间点是从格林威治标准时间1970年1月1日00:00:00以来的毫秒数来衡量的,但原则上这并不重要。)

通常的方式(至少,我一直这样做的方式)是在数据库中存储时间点,所以如果你在下午1点做某事,我会把它看作例如下午3点,因为那是同一个时间点。我的时区。 因此,存储“时间”(HH:MM)而不存储“时间点”的要求,即不调整接收者的时区,这是非常不寻常的,至少在我的经验中。

我会在你使用时使用DATETIME数据类型,但是插入并从Java读取值作为字符串,即使用PreparedStatement上的setString方法和ResultSet上的getString

配置Web应用程序服务器和数据库服务器以使用GMT / UTC时区。 归结为整个代码库和所有层应该使用同一个时区。

有关:

  • 夏令时和时区最佳实践

我要做的是将时间戳存储为long ,代表GMT时间 – 这样,MySQL就无法使用它(并且作为奖励,你将获得更好的精度 – MySQL时间戳只精确到一秒)。 添加单独的列以存储时区,然后在显示给用户之前将其转换为本地时间字符串。

另外,要注意节省日光。 有些地方没有它,它并不总是在所有拥有它的地方同时开始和停止。

MySQL或任何其他标准数据库不存储时区信息。 它只存储Epoch的时间偏移量。 由客户决定特定时区的时间。

但是,在此过程中的某个位置,当客户端和服务器位于不同的时区时,时间值会偏移。

当然,这应该是如何运作的。 如果要强制使用强制时区,可以在将时间戳发送到mysql数据库实例之前应用所需的时区偏移量(您应该使用标准库,例如可怕的内置jdk或joda时间来执行此操作只需加1小时即可。)

通过使用带有Calendar对象的setTimestamp和getTimestamp方法,您应该能够在读取和写入数据库时​​强制使用特定的TimeZone。

这是一个老线程,但没有人发布一个简单的答案。 请改用TIMESTAMP字段。 MySql不对TIMESTAMP进行时区调整,因此它可以为您提供开箱即用的function。

大多数类似的线程试图解决这种缺乏调整问题,但对于你的情况,它可以很好地适应你需要的行为。