MySQL DATETIME和TIMESTAMP改为java.sql.Timestamp改为ZonedDateTime



我想知道这种转换是如何工作的。MySQL服务器(5.6)处理时间戳作为区域调整(和内部存储在/从UTC检索)。它还将DATETIME视为没有区域。

在Java方面,无论哪种情况,我都建议阅读java.sql.Timestamp。是否有一个区域类型转换发生(当通过MySQL-connector 5.1.37)从MySQL的DATETIME到java.sql.Timestamp(如应用客户端系统区域)?

最后,我的服务器和客户端只有一个区域,所以我维护一个特定的ZoneId(在应用程序代码中)来获取ZonedDateTime。但是我想使用ZonedDateTime,来回到存储为DATETIME的数据库。转换的一个简单的例子将受到赞赏!

让我们来回答您的每个问题。第一:

是否有一个区域类型的转换发生(当通过MySQL-connector 5.1.37)从MySQL的DATETIME到java.sql.Timestamp(如应用客户端系统区域)?
首先,我假定您正在使用连接器中的getTimestamp(int)方法。我找不到一个能给我一个启发性答案的官方来源;然而,有这样一个问题,其中的答案是:
当你调用getTimestamp()时,如果类型是时间戳,MySQL JDBC驱动程序将时间从GMT转换为默认时区。对其他类型不执行这样的转换。
但是,在这个版本的方法中,如果底层数据库不存储时区信息,则使用底层CalendarTimestamp转换为指定的TimeZone。这可能是第二个问题的解决方案,只要您知道存储该值的时区(您确实知道)。但如果不是,似乎第一个方法没有发生转换,至少在检索DATETIME时没有。说到你的第二个问题:
但是我想和ZonedDateTime一起工作,来回到数据库存储为DATETIME。
这让我认为有一种方法可以做到这一点,只要你知道哪个时区你从转换。正如我们之前所说,您和您的客户只使用一个ZoneId,这是完全可以的。但是,提供这个答案是为了使用更多的时区。如果要在数据库中存储连接的ZoneId,则可以实现多个ZoneId;检索它和DATETIME,最后将这些值处理成ZonedDateTime。您可以使用ZoneId类的ID将ZoneId存储到数据库中(如果您愿意的话)。

Timestamp t = resultSet.getTimestamp(timestampColumnId);
ZoneId zoneId = ZoneId.of(resultSet.getString(zoneColumnId), ZoneId.SHORT_IDS);
ZonedDateTime d = ZonedDateTime.ofInstant(t.toInstant(), zoneId);

或者,您可以像ZZ Coder在上面的回答中建议的那样,将DATETIME作为TIMESTAMP存储在数据库中。但是,您可以直接使用硬编码的ZoneId:

Timestamp t = resultSet.getTimestamp(timestampColumnId);
ZonedDateTime d = ZonedDateTime.ofInstant(t.toInstant(), zoneId);

编辑
查看源代码,在使用getTimestamp(int, Calendar)setTimestamp(int, Timestamp, Calendar)函数的get或set调用中,使用的是Calendar的时区。但是,在使用TIMESTAMP的某些情况下,当不使用Calendar时,JDBC将使用服务器的时区。根据最初的海报,它起作用了(见下面的评论)。

相关内容

  • 没有找到相关文章

最新更新