按照Java.sql.Timestamp中的原样检索Oracle日期/时间戳字段,而不转换为DST

按照Java.sql.Timestamp中的原样检索Oracle日期/时间戳字段,而不转换为DST,java,oracle,date,jdbc,dst,Java,Oracle,Date,Jdbc,Dst,我在oracle中有一列(LOGIN_TIME)和日期数据类型。我试图使用JDBC在Java中将其作为时间戳来读取。 对于此列,“我的表格”中的一行的值为2006-04-02 02:00:01.0。 当我这样做的时候 从表中选择LOGIN\u TIME,CAST(LOGIN\u TIME作为时间戳) 我看到sql开发人员将该值显示为 2006-04-02 02:00:01.0 但是当我使用ResultSet.getTimestamp()方法在Java中检索这个列值时,我看到的值是2006-04-

我在oracle中有一列(LOGIN_TIME)和日期数据类型。我试图使用JDBC在Java中将其作为时间戳来读取。 对于此列,“我的表格”中的一行的值为2006-04-02 02:00:01.0。 当我这样做的时候

从表中选择LOGIN\u TIME,CAST(LOGIN\u TIME作为时间戳)

我看到sql开发人员将该值显示为

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在插入DB时毫无怨言地接受了此值
  • 但是,由于02:00:01是一个无效时间,Java默认情况下会对其宽大处理,并将时间转换为假定的正确时间03:00:01
  • 现在,我的问题是


  • 为什么java假定正确的时间为03:00:01?它是否依赖于任何时区,如果是,默认时区是什么?我不认为这里的默认时区是UTC,因为
  • System.out.println(+rs.getTimestamp(索引, Calendar.getInstance(TimeZone.getTimeZone(“UTC”))

    给我的价值是

    2006-04-01 18:00:01.0

  • 如果没有JDBC as 2006-04-02 02:00:01.0进行的DST转换,我如何从Oracle按原样检索值?或者将其转换为2006-04-02 03:00:01.0,并将其转换回原始oracle值2006-04-02 02:00:01.0

  • Java中的日期不存储时区。相反,它使用您的本地时区来表示值。这就是为什么你会看到不同的结果

    如果您使用Java8和JDBC4.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中的日期不存储时区。相反,它使用您的本地时区来表示值。这就是为什么你会看到不同的结果

    如果您使用Java8和JDBC4.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);
    

    对不起,有点混乱。我已经编辑了我的问题。我的意思是说Oracle列数据类型是Date,我正试图使用resultSet.getTimestamp()在Java中将其作为时间戳读取;对不起,有点混乱。我已经编辑了我的问题。我的意思是说Oracle列数据类型是Date,我正试图使用resultSet.getTimestamp()在Java中将其作为时间戳读取;“默认时区是什么?”-
    java.time.ZoneId.systemDefault().getId()
    将返回JVM的当前默认时区。好的,这意味着JDBC将该值转换为JVM默认时区。这种情况是否只会发生在丢失/无效时间(由于节省日光而丢失的时间)和所有其他日期,jdbc会给我数据库中的实际值?是的,通常都是这样。那么,有没有办法按原样获取值?i、 e,如果它在oracle中存储为2006-04-02 02:00:01.0,那么有没有办法在没有jdbc默认转换的情况下获得相同的值?这就是
    java.time.LocalDateTime
    的用途。只要你继续使用旧的和不推荐的
    java.sql.Timestamp
    你就会被时区问题困扰。“默认时区是什么?”-
    java.time.ZoneId.systemDefault().getId()
    将返回JVM的当前默认时区。好的,这意味着JDBC将该值转换为JVM默认时区。这种情况是否只会发生在丢失/无效时间(由于节省日光而丢失的时间)和所有其他日期,jdbc会给我数据库中的实际值?是的,通常都是这样。那么,有没有办法按原样获取值?i、 e,如果它在oracle中存储为2006-04-02 02:00:01.0,那么有没有办法在没有jdbc默认转换的情况下获得相同的值?这就是
    java.time.LocalDateTime
    的用途。只要您继续使用旧的和不推荐的
    java.sql.Timestamp
    ,您就会被时区问题困扰。