在多时区服务器上使用JDBC时,我应该选择哪种oracle日期数据类型



我有一个Oracle数据库,它的时区与服务器的时区不同。服务器本身具有不同的时区。

我尝试了几种数据类型:DATE、TIMESTAMP、TIMESTAMPWIThTIMEZONE、TIMESTAmpWIThLOCALTIMEZONE,当与JDBC一起使用时,它们都有不同的问题。请参阅以下问题(我的服务器位于IDT时区,数据库位于PST时域)。

在多时区架构中,哪种日期数据类型正确

要创建具有不同日期类型的表:

create table ALIK_TZ (
D date default sysdate,
t timestamp default systimestamp,
tz timestamp with time zone default systimestamp,
ltz timestamp with local time zone default systimestamp
);

插入值:

insert into ALIK_TZ (d) values (default);

查询:

select to_char(d, 'DD-MON-YYYY HH24:MI:SS') D_SECS, ALIK_TZ.* from ALIK_TZ;

结果:

"D_SECS"     "D"        "T"         "TZ"                            "LTZ"
"01-JUN-2016 06:14:04"  01-JUN-16   01-JUN-16 06.14.04.920000000 AM 01-JUN-16 06.14.04.920000000 AM -07:00  01-JUN-16 04.14.04.920000000 PM
"01-JUN-2016 06:20:54"  01-JUN-16   01-JUN-16 06.20.54.181000000 AM 01-JUN-16 06.20.54.181000000 AM -07:00  01-JUN-16 04.20.54.181000000 PM

使用JDBC进行查询:

preparedStatement = conn.prepareStatement("select * from ALIK_TZ");
resultSet = preparedStatement.executeQuery();

getObject:的结果

D->java.sql.Timestamp(01-JUN-2016 06:14:04)
T->java.sql.Timestamp(2016-06-01 06:14:04.92)
TZ->oracle.sql.TIMESTAMPTZ
LTZ->oracle.sql.TIMESTAMPTZ

正如您所看到的,我不能使用D或t,因为我需要时区中的结果。

关于TZ,如果我使用ResultSet.getTimestamp(4),它将返回java.sql.Timestamp(2016-06-01 16:14:04.92)-在正确的时区中!!!但缺点是我不能在TIMESTAMP WITH TIME ZONE上使用索引。

关于LTZ,我甚至不能使用ResultSet.getTimestamp()。我需要递一份日历。执行resultSet.getTimestamp(5, Calendar.getInstance())返回java.sql.Timestamp(2016-06-01 13:14:04.92)-错误的时区(UTC而不是IDT)。

所以我似乎找不到与JDBC一起使用的完美日期-时间数据类型。想法

*顺便说一句,可以使用longs(从1970 UTC开始的millis),但在查看数据库中的数据时非常麻烦。

我个人建议在数据库端使用TIMESTAMP WITH TIME ZONE,在Java端使用java.time.ZonedDateTime。这使您独立于任何服务器和客户端设置,并允许稍后转换到任何时区,如果您决定这样做的话

唯一的问题是,当您计算和存储未来的日期时,特定时区的时区规则会发生变化。然而,如果你足够早地发现这一点,这是可以纠正的。

相关内容

  • 没有找到相关文章

最新更新