我假设您至少使用 Java 8 和 JDBC 4.2。我进一步假设时间戳在数据库中没有时区或偏移信息,但应理解为 UTC 中的时间戳(这是推荐的做法)。在这种情况下,我认为在 Java 中明确添加有关 UTC 偏移量的信息是最安全的:
PreparedStatement yourPreparedStatement
= yourConnection.prepareStatement("select trade_timestamp from your_table");
ResultSet rs = yourPreparedStatement.executeQuery();
while (rs.next()) {
LocalDateTime tradeDateTime = rs.getObject(1, LocalDateTime.class);
Instant tradeInstant = tradeDateTime.atOffset(ZoneOffset.UTC).toInstant();
System.out.println("Trade Instant: " + tradeInstant);
}
请注意,代码Timestamp
完全避免了过时的类。ALocalDateTime
是没有时区或偏移量的日期和时间。如果您的数据库数据类型是timestamp with time zone
,那么您可能已经传递了Instant.class
or OffsetDateTime.class
tors.getObject
并得到了 aInstant
或 a OffsetDateTime
。JDBC 4.2 只指定支持OffsetDateTime
,但许多驱动程序Instant
也支持。显然Instant
你不需要进一步的转换。用OffsetDateTime
做
Instant tradeInstant = tradeDateTime.toInstant();
根据您的数据库及其功能,您还可以在数据库会话中将 UTC 设置为偏移量/时区,这样即使timestamp
没有时区,您也可以获得正确的瞬间。
讨论: Arvind Kumar Avinash 在评论中建议人们应该只依赖 JDBC 4.2 官方支持的类型,也就是说,LocalDateTime
为了OffsetDateTime
我们的目的。文章底部提到了这些类型为什么我们需要一个新的日期和时间库?在 Oracle 的网站上,底部有一个链接。Arvind Kumar Avinash 进一步向我们推荐 PSQLException: Can't infer the SQL type to use for an instance of java.time.Instant,也链接到底部。由于评论很脆弱,我想在答案中包含这里的本质。
你的代码出了什么问题?
似乎您的数据库会话将时间戳理解为您当地时区的日期和时间(IST,我假设它是印度标准时间(存在其他解释))。根据 Mark Rotteveel 的信息性评论,JDBC 需要这种行为,但是当值是 UTC 时,它不符合您的需要。因此,它给了您错误的时间点,尽管在您打印时它看起来是正确的。转换本身是正确的。
链接