java - 按 Java java.sql.Timestamp 中的方式检索 Oracle 日期/时间戳字段,无需转换为 DST

标签 java oracle date jdbc dst

我在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。

经过大量谷歌搜索后,我明白了

  1. 首先,2006-04-02 02:00:01.0 无效/丢失时间,因为在 2006-04-02 01:59:00.0 之后,由于夏令时,时钟点击 2006-04-02 03:00:00.0。
  2. Oracle 日期/时间戳数据类型不维护时区,因此 Oracle 在插入数据库时​​毫无怨言地接受了该值。
  3. 但是,由于 02:00:01 是无效时间,Java 默认情况下会对其宽容对待,并将时间转换为假定的正确时间 03:00:01。

现在,我的问题是

  1. 为什么 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/

    相关文章:

    java - log4j 1.2.17 extras - 记录到错误的文件

    java - 依赖注入(inject)只针对服务类型对象和单例吗? (而不是图形用户界面?)

    java - 如何在家里自己的机器上测试简单的服务器-客户端应用程序?

    java - 查询通知

    oracle - 在 SELECT INTO 之前使用 SELECT COUNT(*) 是否比使用 Exceptions 慢?

    sql - SQL基础知识(子查询主题)

    php - 向mysql字段添加6个月并减去1周

    c++ - 在 DateEdit Qt C++ 中打开 .txt 中的日期

    java - 不需要的 Dom4J 命名空间

    java - 无法使 JTextArea 可滚动..!