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

时间:2011-03-01 20:39:12

标签: java mysql jdbc timezone

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

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

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

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

7 个答案:

答案 0 :(得分:2)

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

相关:

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

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

  

然而,在某个地方,当客户端和服务器位于不同的时区时,时间值会被抵消。

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

这是一个非常老的线程,但是我发现,如果您使用数据库的时区插入和/或获取Date,它将在任何地方都可以使用:

final Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT+2"));
pst.setDate(0, new java.sql.Date(myDate.getTime()), cal);
(...)
resultSet.getDate("COLUMN_NAME", cal).getTime());

希望这会有所帮助。

答案 6 :(得分:0)

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

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