从Oracle到JDBC的时间戳差异

从Oracle到JDBC的时间戳差异,oracle,jdbc,timestamp,timestamp-with-timezone,Oracle,Jdbc,Timestamp,Timestamp With Timezone,我将Oracle DB(12.2)中的dbtimezone保留为'-07:00'和'America/Los_Angeles',并检索到一个带有'TIMESTAMP with LOCAL TIME ZONE'的列,该列给出了不同的值。它显示了8分钟的差异。请查看下面的查询 ALTER DATABASE ORCL SET TIME_ZONE='America/Los_Angeles'; 关机和启动 创建用户并创建带有时间戳和本地时区的表 create table t_ts(id int, ts t

我将Oracle DB(12.2)中的dbtimezone保留为'-07:00'和'America/Los_Angeles',并检索到一个带有'TIMESTAMP with LOCAL TIME ZONE'的列,该列给出了不同的值。它显示了8分钟的差异。请查看下面的查询

ALTER DATABASE ORCL SET TIME_ZONE='America/Los_Angeles';
关机和启动

创建用户并创建带有
时间戳和本地时区的表

create table t_ts(id int, ts timestamp with local time zone, tst timestamp with time zone);
insert into t_ts values(1, timestamp '0912-02-29 02:02:10.089', timestamp '0912-02-29 02:02:10.089');
我发送了一个查询并使用JDBC获取了行,它给出了:

ID: 1
Epoch time: -33381730189911
TS: 0912-02-29 01:10:10.089
现在我删除表和用户,然后将dbtimezone设置为'-07:00',并执行相同的操作。它给了我不同的结果

ID: 1
Epoch time: -33381730669911
TS: 0912-02-29 01:02:10.089
我有两个问题:

1) 如何在使用JDBC带来时间戳的同时禁用夏令时(一小时的差异是因为给定的时间属于DST)

2) 为什么8分钟的时间差

JDBC版本:

Oracle 12.2.0.1.0 JDBC 4.2 compiled with javac 1.8.0_91 on Tue_Dec_13_06:08:31_PST_2016
我的JDBC代码如下:

ResultSet rs=stmt.executeQuery("select * from t_ts");
while(rs.next()) {
   System.out.println("ID: " + rs.getInt("id"));
   Timestamp ts = rs.getTimestamp("ts");
   System.out.println("Epoch time: " + ts.getTime());
   System.out.println("TS: " + ts);
}
也许可以看看Oracle数据库也在使用哪个


对于
America/Los_Angeles
您可以看到以下条目:

来自Paul Eggert(2018-03-20): 多德的建议留下了许多细节没有解决,比如在哪里画画 时区之间的界线。制造时区的关键人物 在美国工作的是铁路工程师威廉·弗雷德里克·艾伦, 《旅游指南》总编辑兼 通用时间公约,一个铁路标准化组织。艾伦 花了数月时间与科学和铁路领导人进行对话, 制定了建立时区的可行计划,并进行了介绍 在1883年4月11日的普通时间大会上,他说他的计划 意味着“当地时间实际上将被废除”——这对于 铁路调度。到1883-10-11年的下一次大会几乎所有 铁路公司已经同意,并于1883-11-18年生效。那个星期天 被称为“两个中午的一天”,正如一些地方观测到的中午 两次艾伦见证了纽约市的转型,他写道:

我听到了旧时圣保罗罢工的钟声。四 几分钟后,听从海军的电信号 天文台时间球急速下降,钟声响起 旧三一教堂的钟声敲响了十二下,当地时间是 被抛弃,可能永远

我们大多数人很快就效仿了。见: 巴特基·伊尔。采用标准时间。技术崇拜1989年1月;30(1):25-56.


1883年11月18日前的时区<代码> >美国/洛杉矶> <代码>不是<代码> UTC-08> < /代码>但是<代码> UTC-07:52<代码>(UTC的时区偏移只考虑小时/分钟但没有秒)

当您在带有时区的
时间戳
或带有本地时区的
时间戳列中输入
时间戳'0912-02-29 02:02:10.089'
时,Oracle实际执行

FROM_TZ(timestamp '0912-02-29 02:02:10.089', SESSIONTIMEZONE)

您输入的日期
0912-02-29
在1883年之前,但我不知道您为什么会得到不同的结果。也许在某个时候,Oracle忽略了<代码>美国/LoSoLogaleS/<代码>不等于<代码> UTC-08AX 1883之前,可以认为这是一个bug。


无论如何,Oracle建议设置
DBTIMEZONE=UTC
,我认为其他任何设置都没有任何意义

我很确定在0912年(即1000多年前!)根本没有DST。拥有
DBTIMEZONE
America/Los_Angeles
的目的是什么?@WernfriedDomscheit那么如果没有DST为什么会显示一个小时的差异呢?
America/Los_Angeles
也是一个时区,将它用于DBTIMEZONE有什么问题吗?您是否试图从JDBC获取值,作为
java.sql.Timestamp
、作为
oracle.sql.TIMESTAMPLTZ
或作为
java.time.Instant
或其他内容?请添加一个包含java代码的示例,以便我们可以复制该问题。感谢您的回复,这回答了我的第二个问题。关于一小时的差异有什么想法吗?@Srikanth使用不适用DST的
会话时区,即
+08:00
而不是
美国/洛杉矶
对不起,你能详细说明一下吗?在何处使用sessiontimezone?使用
ALTER SESSION SET TIME_ZONE='…'。当您使用带有本地时区的时间戳时,
SESSIONTIMEZONE
实际上是最重要的设置。
FROM_TZ(timestamp '0912-02-29 02:02:10.089', SESSIONTIMEZONE)