你有 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' );
然后您的查询(您不需要TO_TIMESTAMP_TZ
在已经是TIMESTAMP WITH TIME ZONE
列的列上使用):
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 |
| :-------------------- |
| 2021 年 3 月 15 日 00:17:16 |
和作品!
但是,如果您end_date
使用TIMESTAMP
(无时区)存储:
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 |
| :-------------------- |
| 2021 年 3 月 14 日 18:17:16 |
这复制了您的问题。
这是因为数据库不知道数据的时区,并且会隐含地假设它与数据库/会话时区相同,并且我们已将其设置为Asia/Dacca
and not 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 |
| :-------------------- |
| 2021 年 3 月 15 日 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<>在这里摆弄