【发布时间】:2023-04-01 08:20:01
【问题描述】:
所以这是一个遗留系统。 Oracle 11g、java 1.7.0_291-b32、CentOS 7。 我有一个问题,时间减少了一个小时,并且整年都如此(这不仅仅是 DST 翻转的时候)。
这是使用 jdbc 调用具有本地时区数据类型的时区数组的 PL/SQL 过程的 java。请注意,这曾经是 100% 工作的。
所以一个 java.util.Date 数组被转换成一个 java.sql.Timestamp 数组。
public static java.sql.Timestamp[] toTimestamp(Date [] objs) {
java.sql.Timestamp[] tsArray = new java.sql.Timestamp[objs.length];
int i=0;
for(Date d : objs) {
if(d == null)
tsArray[i] = null;
else
tsArray[i] = new java.sql.Timestamp(((Date)d).getTime());
i++;
}
return tsArray;
}
... 我已经确认返回的数组有正确的时间。 然后将数组转换为 oracle.sql.ARRAY 对象
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor( 'TIMEZONE_ARRAY', connection );
ARRAY oracleArray = new ARRAY(descriptor, connection, CollectionsUtil.toTimestamp(array) );
其中 'Timezone_Array' 是数据库中定义的类型,它是具有本地时区的时间戳数组。当转换发生在此处时,时间会从应有的时间调整一个小时。
为了解决这个问题。我首先要确保我的 jdbc 驱动程序是最新的可用于 jdk 7。我运行了 oracle 的时区更新工具,以确保 JDK/JRE 中的时区定义是最新的。我很困惑这怎么不对。
我在 11g 数据库中看到了类似的问题,我必须更新数据库的时区定义文件,此时它很好。我为 JRE 更新的时区信息是 2021a,所以应该没问题。感觉就像一个月前工作的那样,一些定义映射需要更新。 (为什么我更新了时区定义文件)无论如何,如果有人有建议,我会全力以赴。谢谢!
【问题讨论】:
-
毫无疑问是时区问题。 JVM、数据库会话和数据库服务器的默认时区是什么?
-
你如何检查“带有本地时区的时间戳”值,知道它们是一小时的休息时间?假定输入的时区是什么时区(以及附加到来自 Java 的时间戳的位置 - 在 Java 代码中,或者仅在数据到达数据库之后),以及您检查的会话的时区是什么结果?转换为“本地”时区之前的时区与从“本地”时区转换回会话时区后的时区之间的不匹配最有可能是罪魁祸首,而不是时区文件。
-
您可以使用
SELECT DBTIMEZONE FROM dual;查询数据库时区(与UTC的偏移量) -
所以。 jboss 服务器的时区是 Los_Angeles,数据库也是。 java中的会话,在这种情况下,用户是NewYork,时区设置为那个。因此,假设我正在安排一个重复发生的事件,该事件每天从美国东部标准时间中午开始,例如发生 10 次。在java中构造了一个时间戳数组,我附在Jboss服务器上单步执行代码,我可以看到时间实际上是中午。在代码将数组设置为传递给 oracle 的情况下,我在将该数组传递给数据库之前对其进行检查。休息 1 小时。
-
所以 java 时间戳数组很好,但是当使用该时间戳数组初始化“带有本地时区的时间戳表”类型的 Oracle 数组时,时间会被破坏。多年来一直运行良好,直到最近..
标签: java arrays oracle jdbc timestamp