java.sql.Timestamp has a timezone
我读过的所有内容都说时间戳是UTC,没有偏移量或时区。 但是,99%的肯定是MS Sql Server JDBC正在读取数据库中的值并将其设置在我的本地时区。
更新:请不要引用可能重复的问题询问如何使用UTC日期时间设置时间戳。 我的问题是如何从数据库中读取UTC时间戳值。
调试器显示保持为GregorianCalender对象的对象,其时区为Denver。
-
在Date内部某处隐藏了一些时区信息,其中Timestamp是一个子类,因此也适用于该类。它不会影响Timestamp的任何可观察行为,所以我说"有"所有实际目的的"时区"是不正确的。在任何情况下,该类设计很差并且已经过时,因此您不应该使用它,因此无需关心它是否具有时区。
-
使用TimeZone可能重复是java.util.Date吗? (因为Timestamp是java.util.Date的子类)
-
@ OleV.V。不幸的是,时间戳是JDBC返回的。我们立即将其转换为OffsetDateTime,但我们必须处理该转换。
-
时间线处理是一团糟,它取决于数据库设置,会话时区和本地时区(当然还有数据类型)。它由司机变化。使用getTimestamp(x, utccal)变量来指定所需的时区确实很有帮助
-
时间戳是JDBC返回的内容。你的JDBC驱动程序是旧的吗?使用JDBC 4.2执行LocalDateTime dt = yourResultSet.getObject("your_timestamp_col", LocalDateTime.class);。我想这些天大家都在使用JDBC 4.2。
-
我认为你应该在这里找到我对相关问题的回答很有帮助。
-
JDBC规范要求在使用java.sql.Timestamp时在当前时区中解释时间戳,并且除此之外,java.sql.Timestamp.toString()的实现将在当前时区中打印该值。
-
根据Microsoft JDBC驱动程序的SQL Server支持矩阵Microsoft JDBC驱动程序应该支持JDBC 4.2自JDBC驱动程序版本4.2(版本号的巧合)。据我所知,目前的版本是7.2。
-
@ OleV.V。这是我们为客户提供的库。因此,我们必须使用较旧的JDBC驱动程序,因为我们的一些客户仍在使用它们。
这似乎解决了这个问题。 我猜它什么时候返回一个LocalDateTime它不使用时区。
1 2
| LocalDateTime localDT = timestamp.toLocalDateTime();
odt = localDT.atOffset(ZoneOffset.UTC); |
根据@Ole V.V的建议更新
-
从mssql-jdbc v7.1.0开始,驱动程序支持使用rs.getObject(n, java.time.LocalDateTime.class)而不是rs.getTimestamp(n)直接检索LocalDateTime。 (我为它写了PR。)
-
如果由于遗留原因需要继续使用getTimestamp,请注意观察夏令时(a.k.a.夏令时)的时区的"丢失小时"问题。 例如,您无法在America/Denver中检索2019-03-10T02:00:00,因为它从未在该特定时区中发生过。