How to get a java.time object from a java.sql.Timestamp without a JDBC 4.2 driver?
通过JDBC 4.1或更早版本从数据库中检索java.sql.Timestamp时,如何获取/转换为java.time对象?
Postgres的开源JDBC驱动程序都没有兼容JDBC 4.2,所以我正在寻找一种方法来使用java.time和JDBC 4.1。
-
请问为什么你需要使用java.time,这似乎是新的1.8类?
-
因为java.util.Date& .Calendar是出了名的麻烦。 我通常使用Joda-Time代替。 但是我一直在Java 8中使用java.time.java.time包的灵感来自于Joda-Time,但它是重新设计的。
-
更新:虽然我接受了pickypg的答案正确解决了我的问题的具体细节,但最好的解决方案是只使用带有JDBC 4.2的java.time类,同时完全避免麻烦的遗留java.sql类。 直接与数据库交换java.time对象; 不再需要转换了。 请参阅skrueger的答案。
旧类的新方法
通过在Java 8及更高版本中使用驱动程序,您应该自动在java.sql.Timestamp对象上自行选取一些方法。 java.sql.Time和java.sql.Date都有类似的转换方法。
也就是说,要从java.sql转换为java.time,您正在寻找:
-
Timestamp::toInstant()
-
Timestamp::toLocalDateTime()
-
Date::toLocalDate()
-
<5233>
要从另一个方向,从java.time到java.sql,请使用新的静态方法:
-
Timestamp.from(instant)
-
Timestamp.valueOf(localDateTime)
-
Date.valueOf(localDate)
-
Time.valueOf(localTime)
例:
1
| preparedStatement. setTimestamp( 2, Timestamp. from(instant ) ); |
-
感谢您的回答和见解。我专注于JDBC驱动程序,并没有考虑查看java.sql.Timestamp类的新功能。
-
仅供参考,在本答案中获得Instant之后,您可以应用ZoneOffset来获取OffsetDateTime,或者更好地应用ZoneId来获取ZonedDateTime。有关详细信息,请参阅我的答案和另一个问题的图表。
-
即将发布的版本应该支持java 8时间API:jdbc.postgresql.org/documentation/head/8-date-time.html
-
当使用TIMESTAMP类型的列(没有时区,我认为它等同于LocalDateTime)时,JDBC会使用什么时区将TIMESTAMP转换为瞬间?
-
如果要将时间戳存储到数据库中,则应将它们存储为UTC。否则,我认为你是对的。有关详细信息,请参阅此setTimestamp答案。
-
给出的示例(至少在使用Microsoft JDBC实现时)会导致将JVM的本地日期时间写入数据库,而不是UTC中的日期时间。采用Calendar实例的setTimestamp()方法有一个覆盖,因此您可以提供所需的时区。
无需转换
正如其他人在评论中所说,PostgreSQL的JDBC驱动程序现在支持JDBC 4.2,包括Java 8 Time API支持。我们可以直接用数据库交换java.time对象。
https://jdbc.postgresql.org/documentation/head/8-date-time.html
所以不需要转换,也不需要再次使用java.sql类型。仅使用java.time包中的替换项,如此列表中所示。
1 2 3 4 5
| PostgreSQL? Java SE 8 (java.time)
DATE LocalDate
TIME [ WITHOUT TIMEZONE ] LocalTime
TIMESTAMP [ WITHOUT TIMEZONE ] LocalDateTime
TIMESTAMP WITH TIMEZONE OffsetDateTime or Instant |
这可以通过ResultSet::getObject检索
1 2 3 4
| ResultSet rs = ... ;
while (rs. next()) {
LocalDate localDate = rs. getObject(1, LocalDate. class));
} |
通过调用PreparedStatement::setObject存储java.time对象。
1
| myPreparedStatement.setObject( … , myInstant ) ; |
-
本答复是一个非常重要的更新。坚持使用java.time类确实是要走的路。