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

问题描述 投票:2回答:7

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

拥有此值的数据库列的类型为DATETIME,因为我印象中它不进行时区调整。 Java应用程序将时间戳作为java.util.Date对象接收,并将其转换为java.sql.Timestamp对象,然后再将它们插入PreparedStatements中。但是,当客户端和服务器位于不同时区时,时间值会偏移。

为了让您了解所要查找的内容,我可以将所有时间戳记存储为字符串,而这正是我想要的效果,但是对于我来说,必须将其格式化和解析为需要对其进行操作的日期。

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

java mysql jdbc timezone
7个回答
1
投票

麻烦是java.util.Date代表一个“时间点”,而不是像18:00这样的时间。 (在这种情况下,时间点是指自格林威治标准时间1970年1月1日00:00:00以来的毫秒数,但原则上在这里无关紧要。)

通常的方式(至少,我一直这样做)是将时间点存储在数据库中,因此,如果您在下午1点执行某项操作,我将其视为例如下午3点,因为那是我所在时区的同一时间。因此,至少在我的经验中,存储“时间”(HH:MM)而不存储“时间点”(即不调整收件人的时区)的要求是非常不寻常的。

我将在使用时使用DATETIME数据类型,但是从Java中以字符串形式插入和读取值,即使用setString上的PreparedStatement方法和getString上的ResultSet

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

将Web应用程序服务器和数据库服务器都配置为使用GMT / UTC的时区。归结为entire

代码库和all
层应使用相同的时区。

相关:

[我要做的是将时间戳记存储为long,代表格林尼治标准时间-这样,MySQL便无法解决它(而且,作为奖励,您将获得更好的精度-仅MySQL时间戳记精确到一秒钟)。添加单独的列以存储时区,然后在显示给用户之前将其转换为本地时间字符串。

此外,请注意夏令时。有些地方没有它,并且在所有拥有它的地方,它并不总是同时启动和停止。

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

但是,当客户端和服务器位于不同时区时,时间值会偏移。

当然,这就是它的工作方式。如果要强制使用强制性时区,则可以在将时间戳发送到mysql数据库实例之前应用所需的时区偏移量(应使用标准库,例如djd内置的djd库或joda time库来代替,只需加上或减去1小时)。

这是一个旧主题,但是没有人发布一个简单的答案。请改用TIMESTAMP字段。 MySql不会为TIMESTAMP进行时区调整,因此它可以为您方便地使用。

[大多数类似的线程都在尝试解决这种缺乏调整的问题,但是对于您的情况,它可以很好地满足您所需的行为。

这是一个非常老的线程,但是我发现如果您使用数据库的时区插入和/或获取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());

希望这会有所帮助。


2
投票

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


2
投票

将Web应用程序服务器和数据库服务器都配置为使用GMT / UTC的时区。归结为entire


1
投票

[我要做的是将时间戳记存储为long,代表格林尼治标准时间-这样,MySQL便无法解决它(而且,作为奖励,您将获得更好的精度-仅MySQL时间戳记精确到一秒钟)。添加单独的列以存储时区,然后在显示给用户之前将其转换为本地时间字符串。


1
投票

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


0
投票

这是一个旧主题,但是没有人发布一个简单的答案。请改用TIMESTAMP字段。 MySql不会为TIMESTAMP进行时区调整,因此它可以为您方便地使用。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.