将日期从 UTC 时区转换为 PST 时区(包括 DST 因素)
Convert a date from UTC timezone to PST Time zone (including DST factor)
我想将 UTC 时区的日期转换为 PST 时区。 NEW_TIME 没有考虑 DST(夏令时)因素,所以我尝试使用 CAST 和 TO_TIMESTAMP_TZ 函数,但都给出了不正确的时间(相差大约 5 小时 30 分钟)。不知道为什么。
SELECT TO_CHAR(TO_TIMESTAMP_TZ(max(end_date) AT TIME ZONE 'PST')
,'DD-MON-YYYY HH24:MI:SS')
FROM table1
WHERE NAME= 'FIRST';
SELECT TO_CHAR(CAST((max(end_date) AT TIME ZONE 'PST') AS DATE )
,'DD-MON-YYYY HH24:MI:SS')
FROM table1
WHERE NAME= 'FIRST';
我也尝试使用 'US/PACIFIC' 而不是 'PST',但它也给出了相同的结果。
max(end_date) 是:2021-03-15 07:17:16(UTC)
查询正在返回(返回的时间不正确):2021 年 3 月 14 日18:47:16
应该的时间(预计正确时间):2021 年 3 月 15 日00:17:16
任何人都可以帮助更正我的查询或任何其他可以将日期从 UTC 转换为 PST 时区的函数(记住 DST 因素)。
你们有 6 个小时的时差,所以我假设你们和 Asia/Dacca
处于同一时区,并且已经使用以下方法设置了我的会话:
ALTER SESSION SET TIME_ZONE='Asia/Dacca';
现在,如果我创建 table1
数据类型 TIMESTAMP WITH TIME ZONE
:
CREATE TABLE table1 (
name VARCHAR2(20),
end_date TIMESTAMP WITH TIME ZONE
);
INSERT INTO table1 ( name, end_date ) VALUES ( 'FIRST', TIMESTAMP '2021-03-15 07:17:16 UTC' );
然后你的查询(你不需要在已经是 TIMESTAMP WITH TIME ZONE
列的列上使用 TO_TIMESTAMP_TZ
):
SELECT TO_CHAR(
max(end_date) AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
输出:
| PST_END_DATE |
| :------------------- |
| 15-MAR-2021 00:17:16 |
并且有效!
但是,如果您使用 TIMESTAMP
(不带时区)存储 end_date
:
CREATE TABLE table1 (
name VARCHAR2(20),
end_date TIMESTAMP
);
INSERT INTO table1 ( name, end_date ) VALUES ( 'FIRST', TIMESTAMP '2021-03-15 07:17:16' );
然后:
SELECT TO_CHAR(
max(end_date) AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
输出:
| PST_END_DATE |
| :------------------- |
| 14-MAR-2021 18:17:16 |
这重复了您的问题。
这是因为数据库不知道数据的时区,并且会隐含地假定它与 database/session 时区相同,我们已将其设置为 Asia/Dacca
和不是 UTC
。相反,我们需要明确告诉数据库使用 UTC
时区进行转换:
SELECT TO_CHAR(
FROM_TZ(max(end_date), 'UTC') AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
输出:
| PST_END_DATE |
| :------------------- |
| 15-MAR-2021 00:17:16 |
如果您的列具有 DATE
数据类型:
CREATE TABLE table1 (
name VARCHAR2(20),
end_date DATE
);
INSERT INTO table1 ( name, end_date ) VALUES ( 'FIRST', TIMESTAMP '2021-03-15 07:17:16' );
然后您可以使用相同的查询并添加 CAST
:
SELECT TO_CHAR(
FROM_TZ(CAST(max(end_date) AS TIMESTAMP), 'UTC') AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
db<>fiddle here
我想将 UTC 时区的日期转换为 PST 时区。 NEW_TIME 没有考虑 DST(夏令时)因素,所以我尝试使用 CAST 和 TO_TIMESTAMP_TZ 函数,但都给出了不正确的时间(相差大约 5 小时 30 分钟)。不知道为什么。
SELECT TO_CHAR(TO_TIMESTAMP_TZ(max(end_date) AT TIME ZONE 'PST')
,'DD-MON-YYYY HH24:MI:SS')
FROM table1
WHERE NAME= 'FIRST';
SELECT TO_CHAR(CAST((max(end_date) AT TIME ZONE 'PST') AS DATE )
,'DD-MON-YYYY HH24:MI:SS')
FROM table1
WHERE NAME= 'FIRST';
我也尝试使用 'US/PACIFIC' 而不是 'PST',但它也给出了相同的结果。
max(end_date) 是:2021-03-15 07:17:16(UTC)
查询正在返回(返回的时间不正确):2021 年 3 月 14 日18:47:16
应该的时间(预计正确时间):2021 年 3 月 15 日00:17:16
任何人都可以帮助更正我的查询或任何其他可以将日期从 UTC 转换为 PST 时区的函数(记住 DST 因素)。
你们有 6 个小时的时差,所以我假设你们和 Asia/Dacca
处于同一时区,并且已经使用以下方法设置了我的会话:
ALTER SESSION SET TIME_ZONE='Asia/Dacca';
现在,如果我创建 table1
数据类型 TIMESTAMP WITH TIME ZONE
:
CREATE TABLE table1 (
name VARCHAR2(20),
end_date TIMESTAMP WITH TIME ZONE
);
INSERT INTO table1 ( name, end_date ) VALUES ( 'FIRST', TIMESTAMP '2021-03-15 07:17:16 UTC' );
然后你的查询(你不需要在已经是 TIMESTAMP WITH TIME ZONE
列的列上使用 TO_TIMESTAMP_TZ
):
SELECT TO_CHAR(
max(end_date) AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
输出:
| PST_END_DATE | | :------------------- | | 15-MAR-2021 00:17:16 |
并且有效!
但是,如果您使用 TIMESTAMP
(不带时区)存储 end_date
:
CREATE TABLE table1 (
name VARCHAR2(20),
end_date TIMESTAMP
);
INSERT INTO table1 ( name, end_date ) VALUES ( 'FIRST', TIMESTAMP '2021-03-15 07:17:16' );
然后:
SELECT TO_CHAR(
max(end_date) AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
输出:
| PST_END_DATE | | :------------------- | | 14-MAR-2021 18:17:16 |
这重复了您的问题。
这是因为数据库不知道数据的时区,并且会隐含地假定它与 database/session 时区相同,我们已将其设置为 Asia/Dacca
和不是 UTC
。相反,我们需要明确告诉数据库使用 UTC
时区进行转换:
SELECT TO_CHAR(
FROM_TZ(max(end_date), 'UTC') AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
输出:
| PST_END_DATE | | :------------------- | | 15-MAR-2021 00:17:16 |
如果您的列具有 DATE
数据类型:
CREATE TABLE table1 (
name VARCHAR2(20),
end_date DATE
);
INSERT INTO table1 ( name, end_date ) VALUES ( 'FIRST', TIMESTAMP '2021-03-15 07:17:16' );
然后您可以使用相同的查询并添加 CAST
:
SELECT TO_CHAR(
FROM_TZ(CAST(max(end_date) AS TIMESTAMP), 'UTC') AT TIME ZONE 'PST',
'DD-MON-YYYY HH24:MI:SS'
) AS pst_end_date
FROM table1
WHERE NAME = 'FIRST';
db<>fiddle here