我在oracle中有一个DATE数据类型的列(LOGIN_TIME)。我正在尝试使用 JDBC 将其读取为 Java 中的时间戳。 我的表中的某一行此列的值为 2006-04-02 02:00:01.0。 当我这样做时
select LOGIN_TIME,CAST(LOGIN_TIME as TIMESTAMP) from TABLE;
我看到 sql-developer 显示的值是
2006-04-02 02:00:01.0
但是当我使用 ResultSet.getTimestamp() 方法在 Java 中检索此列值时,我看到该值为 2006-04-02 03:00:01.0。
经过大量谷歌搜索后,我明白了
- 首先,2006-04-02 02:00:01.0 无效/丢失时间,因为在 2006-04-02 01:59:00.0 之后,由于夏令时,时钟点击 2006-04-02 03:00:00.0。
- Oracle 日期/时间戳数据类型不维护时区,因此 Oracle 在插入数据库时毫无怨言地接受了该值。
- 但是,由于 02:00:01 是无效时间,Java 默认情况下会对其宽容对待,并将时间转换为假定的正确时间 03:00:01。
现在,我的问题是
- 为什么 java 假定正确的时间为 03:00:01?它是否依赖于任何时区,如果是,默认时区是什么?我不认为这里的默认时区是 UTC,因为
System.out.println(+rs.getTimestamp(index, Calendar.getInstance(TimeZone.getTimeZone("UTC"))));
给我的值为
2006-04-01 18:00:01.0
- 如何从 Oracle 中按原样检索值,而不通过 JDBC 将 DST 转换为 2006-04-02 02:00:01.0?或者将其获取为 2006-04-02 03:00:01.0 并将其转换回原始 oracle 值 2006-04-02 02:00:01.0。
最佳答案
Java 中的
Date
不存储时区。相反,它使用您的本地时区来表示值。这就是为什么您会看到不同的结果。
如果您使用 Java 8 和 JDBC 4.2,您可能需要使用更可靠的 java.time.*
包。就这么简单:
LocalDateTime dateTime = rs.getObject(index, LocalDateTime.class);
如果你想将LocalDateTime
转换为java.util.Date
,你可以这样做:
Instant instant = dateTime.atZone(ZoneId.systemDefault()).toInstant();
Date dateFromOld = Date.from(instant);
关于java - 按 Java java.sql.Timestamp 中的方式检索 Oracle 日期/时间戳字段,无需转换为 DST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55234443/