JDBC + MySQL 可以忽略时区吗?

3
我有一个Java Web应用程序,在其中客户端向服务器发送带时间戳的数据以存储在MySQL数据库中并稍后检索。这些时间戳应始终被视为本地时间,不应根据时区进行调整:如果一个时区中的客户端输入了18:00:00的时间,则在另一个时区的客户端中应显示为18:00:00。
持有此值的数据库列的类型为DATETIME,因为我认为它不会进行时区调整。Java应用程序接收java.util.Date对象作为时间戳,并在将它们插入到PreparedStatement之前将它们转换为java.sql.Timestamp对象。然而,在客户端和服务器处于不同的时区时,某个地方的时间值会偏移。
为了给您一个想法,我可以将所有时间戳都存储为字符串,这将完全达到我想要的效果,但是我认为在需要操作日期时将其格式化和解析为字符串是没有意义的。
当时间戳值应始终被视为本地时间时,通常如何处理此类应用程序?
7个回答

2
你应该能够通过使用接受Calendar对象的setTimestamp和getTimestamp方法,在读写数据库时强制使用特定的时区。

2

配置 Web 应用服务器和数据库服务器使用 GMT/UTC 时区。这意味着整个代码库和所有层面都应该使用同一个时区。

相关链接:


1

问题在于java.util.Date表示的是“时间点”,而不是像18:00那样的时间。(在这种情况下,“时间点”是指自1970年1月1日00:00:00 GMT以来的毫秒数,但原则上这在此并不重要。)

通常的方法(至少我一直以来都是这么做的)是将时间点存储在数据库中,因此如果您在当地时间下午1点进行某项操作,我会在我的时区中看到它相当于下午3点的时间点。因此,在不调整接收者的时区的情况下存储“时间”(HH:MM),即不存储“时间点”的要求是相当不寻常的,至少在我的经验中是如此。

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


1
我会将时间戳存储为代表格林威治标准时间的long类型,这样MySQL就无法对其进行更改(并且作为奖励,您将获得更好的精度 - MySQL时间戳仅精确到一秒)。添加一个单独的列来存储时区,然后在显示给用户之前将其转换为本地时间字符串。
此外,请注意夏令时。有些地方没有夏令时,而且并不总是在所有有夏令时的地方同时开始和结束。

1

MySQL或任何其他标准数据库都不存储时区信息。它只存储相对于纪元的时间偏移量。由客户端确定特定时区的时间。

然而,在客户端和服务器处于不同的时区时,时间值会发生偏移。

当然,这就是应该的工作方式。如果您想强制使用强制性时区,则可以在将时间戳发送到mysql数据库实例之前应用所需的时区偏移量(您应该使用标准库,如可怕的内置jdk库或joda时间来执行此操作,而不仅仅是添加或减去1小时)。


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());

希望这有所帮助。

0

这是一个旧的帖子,但没有人发布简单的答案。使用TIMESTAMP字段代替。MySql不会为TIMESTAMP进行时区调整,因此它将直接为您工作。

大多数类似的帖子都试图解决这种缺乏调整的问题,但对于您的情况,它与您需要的行为相匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接