如果 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
我有一个 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