java.sql.timestamp 转换为 oracle 数组关闭 1 小时
java.sql.timestamp conversion to oracle array off by 1 hour
所以这是一个遗留系统。
Oracle 11g,java 1.7.0_291-b32,CentOS 7。
我有一个问题,时间减少了一个小时,并且整年都如此(这不仅仅是在 DST 翻转的时候)。
这是 java 使用 jdbc 调用 PL/SQL 过程,其中包含具有本地时区数据类型的时区数组。请注意,这曾经 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,所以应该没问题。感觉有些定义映射需要更新,因为它在一个月前就起作用了。 (为什么我更新了时区定义文件)无论如何,如果有人有建议,我会洗耳恭听。谢谢!
所以。没有简单的方法来总结这一点。
我正在处理 dbtimezone --> Oracle 的默认时区,它是 GMT 的偏移量(或者应该是)。
我的 jvm 时区可以基于系统环境(我的应用程序基于配置条目)。
登录我的系统的用户有他们所在的特定时区,并且他们的会话设置为反映这一点。
为此,我们使用了带有本地时区的 Oracle 时间戳。它在时区(请参阅 dbtimezone)时间中存储 date/time,但没有关于它的时区信息。
Oracle 将使用您配置的连接时区,并自动调整显示给用户的时区时间。
最重要的是,这是在 Java 7 中,并且大部分都使用蹩脚的 java.util.Date。
整个系统在过去十年中一直完美运行,直到今年。
首先。我必须更新 RDBMS 的时区信息。这修复了所有时区作为单身人士传递的问题。但是,它没有修复正在传递的相同类型的数组。
我的解决方法是使用 oracle 的 to_timestamp_tz 并传递一个字符串数组。使用 SimpleFormater 的 java.util.Date 字符串表示可以显示时区。我知道那个日期是不知道时区的。但是我的会话 IS 配置了时区,当您拉出字符串时会反映出来。 (并且存储在日期中的时间是时区适用时间)。
由于 jdbc/java 拒绝了所有使其成为非延迟的尝试(它正在将时间更改为 dbtimezone 但没有正确执行 ti,休息了一个小时)我只是传递了这个字符串并在 PL/SQL to_timestamp_tz 的程序将其放入具有本地时区字段的时区。 Oracle 处理将其从 to_timestamp_tz 中表示的时区更改为数据库的时区,没有任何障碍。
所以我没有 修复 代码,而是围绕 bug 进行编码。
所以一个简单的方法来获取日期数组和 return 返回一个字符串数组。
public static String[] toTimestampString(Date [] objs, String timestampPattern) {
int i=0;
String[] tsArray = new String[objs.length];
Format formatter = new SimpleDateFormat(timestampPattern);
for (Date d: objs) {
if (d == null)
tsArray = null;
else {
tsArray[i] = formatter.format(d);
i++;
}
}
return tsArray;
}
然后将此数组传递给 PL/SQL,它基本上是这样做的:to_timestamp_tz(p_start_datetime(i),timestampPattern)
oracle 中的 timestampPattern 在 java 中略有不同,基本上在 java 中是“yyyy-MM-dd HH:mm XXX”
在 PL/SQL 中是:'yyyy-MM-dd HH24:mi tzr'
但他们的意思是一样的。我已经在大约 6 个不同的用户时区(夏令时、AZ 和其他非日光)中进行了测试,它正在 100% 工作。
thx 希望这能帮助其他被困在时区地狱中的可怜人。
所以这是一个遗留系统。 Oracle 11g,java 1.7.0_291-b32,CentOS 7。 我有一个问题,时间减少了一个小时,并且整年都如此(这不仅仅是在 DST 翻转的时候)。
这是 java 使用 jdbc 调用 PL/SQL 过程,其中包含具有本地时区数据类型的时区数组。请注意,这曾经 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,所以应该没问题。感觉有些定义映射需要更新,因为它在一个月前就起作用了。 (为什么我更新了时区定义文件)无论如何,如果有人有建议,我会洗耳恭听。谢谢!
所以。没有简单的方法来总结这一点。 我正在处理 dbtimezone --> Oracle 的默认时区,它是 GMT 的偏移量(或者应该是)。 我的 jvm 时区可以基于系统环境(我的应用程序基于配置条目)。 登录我的系统的用户有他们所在的特定时区,并且他们的会话设置为反映这一点。 为此,我们使用了带有本地时区的 Oracle 时间戳。它在时区(请参阅 dbtimezone)时间中存储 date/time,但没有关于它的时区信息。 Oracle 将使用您配置的连接时区,并自动调整显示给用户的时区时间。 最重要的是,这是在 Java 7 中,并且大部分都使用蹩脚的 java.util.Date。 整个系统在过去十年中一直完美运行,直到今年。 首先。我必须更新 RDBMS 的时区信息。这修复了所有时区作为单身人士传递的问题。但是,它没有修复正在传递的相同类型的数组。 我的解决方法是使用 oracle 的 to_timestamp_tz 并传递一个字符串数组。使用 SimpleFormater 的 java.util.Date 字符串表示可以显示时区。我知道那个日期是不知道时区的。但是我的会话 IS 配置了时区,当您拉出字符串时会反映出来。 (并且存储在日期中的时间是时区适用时间)。 由于 jdbc/java 拒绝了所有使其成为非延迟的尝试(它正在将时间更改为 dbtimezone 但没有正确执行 ti,休息了一个小时)我只是传递了这个字符串并在 PL/SQL to_timestamp_tz 的程序将其放入具有本地时区字段的时区。 Oracle 处理将其从 to_timestamp_tz 中表示的时区更改为数据库的时区,没有任何障碍。 所以我没有 修复 代码,而是围绕 bug 进行编码。 所以一个简单的方法来获取日期数组和 return 返回一个字符串数组。
public static String[] toTimestampString(Date [] objs, String timestampPattern) {
int i=0;
String[] tsArray = new String[objs.length];
Format formatter = new SimpleDateFormat(timestampPattern);
for (Date d: objs) {
if (d == null)
tsArray = null;
else {
tsArray[i] = formatter.format(d);
i++;
}
}
return tsArray;
}
然后将此数组传递给 PL/SQL,它基本上是这样做的:to_timestamp_tz(p_start_datetime(i),timestampPattern)
oracle 中的 timestampPattern 在 java 中略有不同,基本上在 java 中是“yyyy-MM-dd HH:mm XXX” 在 PL/SQL 中是:'yyyy-MM-dd HH24:mi tzr' 但他们的意思是一样的。我已经在大约 6 个不同的用户时区(夏令时、AZ 和其他非日光)中进行了测试,它正在 100% 工作。 thx 希望这能帮助其他被困在时区地狱中的可怜人。