当前位置:  开发笔记 > 编程语言 > 正文

JDBC是否在将日期插入Oracle DB之前调整日期?我该如何防止这种情况?

如何解决《JDBC是否在将日期插入OracleDB之前调整日期?我该如何防止这种情况?》经验,为你挑选了1个好方法。

假设我们有以下代码创建日期:

SimpleDateFormat sdf = new SimpleDateFormat( "dd/MM/yyyy" );
sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); // we know the date being parsed is UTC
Date bizDate = sdf.parse( "12/12/2015" ); // milliseconds: 1449878400000
log.info( "ms: {}", bizDate.getTime() );
log.info( "date: {}", bizDate );
... // save to db

如果该代码在UTC上的Oracle数据库上以UTC格式运行,我得到:

JVM参数:-Duser.timezone = UTC

millisecond: 1449878400000
date: Sat Dec 12 00:00:00 UTC 2015
in oracle db: 2015-Dec-12 00:00:00 // zero time

对于未设置为UTC的JVM(例如SGT),我得到:

JVM参数:无(默认时区为SGT或UTC + 8:00)

millisecond: 1449878400000
date: Sat Dec 12 08:00:00 SGT 2015
in oracle db: 2015-Dec-12 08:00:00 // plus 8 hours

请注意,它们都具有相同的毫秒数,但它们在数据库中的插入方式不同.

我的问题是:

    JDBC标准是否说它在插入之前调整Date对象?请引用你的消息来源.

    如果在JVM的时区未设置为UTC时,JDBC确实在将Date对象插入数据库之前调整了它,那么为什么这样设计呢?我觉得这让它更加混乱.我原以为它会按原样插入它.想象一下,如果你使用毫秒创建一个日期(例如新的日期(1449878400000L)),它将以不同的方式存储,你没有关于你的代码将运行的JVM时区的信息.或者想象你的代码将在多个设置为JVM的JVM上运行不同的时区.

    当JVM的时区设置为UTC以外的任何其他时,如何阻止JDBC调整日期?我正在使用ibatis,我可能无法直接访问PreparedStatements.

我已将SimpleDateFormat的时区设置为UTC,因为我想将被解析的日期视为UTC(或根据需要将其他时区视为).如果没有这样的要求,那就不成问题了.现在看来我需要调整Date来反转JDBC在插入之前所做的事情.



1> Andreas..:

问题是Java Date对象不存储时区.该值始终为UTC,并在给定时区(通常是JVM的默认时区)中进行解析和格式化.

Oracle DATE列也不存储时区,但应表示用户看到的日期.在99.99%的情况下,这意味着JVM默认时区中的日期.

因此,JDBC驱动程序采用UTC中的Timestamp/ Date值将其转换为默认时区,并将其保存到数据库中.

您正在使用该PreparedStatement.setTimestamp(int parameterIndex, Timestamp x)方法.要控制时区,请使用该PreparedStatement.setTimestamp(int parameterIndex, Timestamp x, Calendar cal)方法.引用javadoc:

java.sql.Timestamp使用给定Calendar对象将指定参数设置为给定值.驱动程序使用该Calendar对象构造一个SQL TIMESTAMP值,然后驱动程序将其发送到数据库.使用Calendar对象,驱动程序可以计算考虑自定义时区的时间戳.如果未Calendar指定任何对象,则驱动程序将使用默认时区,即运行应用程序的虚拟机的时区.

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有