如果 Oracle 的 dbTimezone 不同,如何将所有日期视为 UTC?

How to treat all dates as UTC if Oracle's dbTimezone is different?

我有一个 Oracle 数据库,它给出 +00:00 查询结果:

select dbTimezone from dual;

我想在我的 Java 应用程序中使用任何 date/time 始终作为 UTC。

我使用的 table 有一个类型为 Date 的列,它从 sysdate.

获取默认值

即使我 运行 我的应用程序 -Duser.timezone=UTC,当我插入此 table 并使用 rs.getTimestamp("DATE_CREATED") 阅读此 Date 列时,它是比预期当前 UTC 时间多一小时:

Expected current UTC: 2020-02-04 20:38:12.0
Actual: 2020-02-04 21:38:12.0

我还注意到 select current_date from dual 而不是 sysdate 将导致预期的当前 UTC 时间。我应该将此列的默认值从 sysdate 更改为 current_date (alter table MY_TABLE modify DATE_CREATED default current_date) 还是有其他方法可以在不更改数据库设置的情况下在 Java 应用程序中配置时区?

您可以从日期中获取以毫秒为单位的时间并转换为您想要的格式:

OffsetDateTime now = OffsetDateTime.now(ZoneOffset.of("+02:00"));
System.out.println("+02:00: " + now); //+02:00: 2020-02-04T22:59:11.617457100+02:00
System.out.println("+02:00 in millis: " + now.toInstant().toEpochMilli()); //+02:00 in millis: 1580849951617

OffsetDateTime utc = Instant.ofEpochMilli(now.toInstant().toEpochMilli()).atOffset(ZoneOffset.UTC); 
System.out.println("UTC: " + utc); //UTC: 2020-02-04T20:59:11.617Z
System.out.println("UTC in millis: " + utc.toInstant().toEpochMilli()); //UTC in millis: 1580849951617

以毫秒为单位的时间应该始终相同。

您可以使用:

CREATE TABLE mytable (
  id NUMBER PRIMARY KEY,
  date_created DATE
);

ALTER TABLE mytable MODIFY date_created DEFAULT SYSTIMESTAMP AT TIME ZONE 'UTC';

(系统时间戳将转换为 UTC 时区,然后隐式转换为默认值的 DATE 数据类型。)

然后:

INSERT INTO mytable( id ) VALUES ( 1 );

SELECT * FROM mytable;

输出:

ID | DATE_CREATED       
-: | :------------------
 1 | 2020-02-04 21:57:47

db<>fiddle here