【发布时间】:2018-05-13 07:07:24
【问题描述】:
我在 oracle DB 中创建了示例表,如下所示
"CREATED_ON" TIMESTAMP (6),
"CREATED_ON_TIMEZONE" TIMESTAMP (6) WITH TIME ZONE,
"TIMEZONE_GMT" TIMESTAMP (6) WITH TIME ZONE
并从java中插入值如下
preparedStatement.setTimestamp(1, new Timestamp(new Date().getTime()));
preparedStatement.setTimestamp(2, new Timestamp(new Date().getTime()));
preparedStatement.setTimestamp(3, new Timestamp(new Date().getTime()) ,Calendar.getInstance(TimeZone.getTimeZone("UTC")));
亚洲/加尔各答的 JVM 时区。我使用 SQL 开发人员来查询数据。 我只是想澄清一下我的理解
根据本地 JVM 存储的第一列没有时区,因为 dataType 只是时间戳,即 29-NOV-17 07.04.28.014000000 PM。因此对于具有 timstamp 数据类型的列,DB 存储的值是由 JDBC 驱动程序传递的本地 JVM 的值,并且 JDBC 端或 DB 端都没有发生转换?
带有 TIMEZONE 的第二列存储值,即 29-NOV-17 07.04.28.014000000 PM 亚洲/加尔各答。那么这是否意味着 DB 使用 JDBC 驱动程序提供的时区信息存储列的值,并且在 DB 端没有转换?
我想在 GMT 中存储值,所以我将第三个参数设置为 GMT,它在 GMT 中存储值,但时区仍显示为本地 JVM。即 29-NOV-17 01.34.28.014000000 PM ASIA/CALCUTTA
我指的是下面的文章,但我的观察结果看起来完全不同。 http://brian.pontarelli.com/2011/08/16/database-handling-for-timezones/
【问题讨论】:
-
这些都是不同的值吗?如果不是,即如果它们代表同一时间,我将建议一个虚拟列作为
TIMEZONE_GMT TIMESTAMP(6) GENERATED ALWAYS AS ( SYS_EXTRACT_UTC(CREATED_ON_TIMEZONE) ) VIRTUALresp。CREATED_ON TIMESTAMP(6) GENERATED ALWAYS AS ( CAST(CREATED_ON_TIMEZONE AS TIMESTAMP(6)) ) VIRTUAL -
更新问题。这些是相同的值。主要问题是第三列,它显示正确的 GMT 值,但时区不同。应该是格林威治标准时间。
-
如果您想保留时区,您需要通过
setObject()传递oracle.sql.TIMESTAMPTZ的实例。 -
你不能使用 Java 8 和
java.time吗?如果可以,请跳过过时的Timestamp课程。我相信您应该将LocalDateTime对象保存到时间戳列中,并将Instant对象保存到带有时区列的时间戳中。在这两种情况下都使用PreparedStatement.setObject()。java.time使用起来更好。