1

我想将 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';

除了“PST”,我还尝试使用“US/PACIFIC”,但它也给出了相同的结果。

max(end_date) 是 : 2021-03-15 07:17:16 (UTC)

查询返回(返回时间不正确):14-MAR-2021 18:47:16

它应该的时间(预期的正确时间):15-MAR-2021 00:17:16

任何人都可以帮助纠正我的查询或任何其他可以将日期从 UTC 转换为 PST 时区的函数(记住 DST 因素)。

4

1 回答 1

1

你有 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/Daccaand 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<>在这里摆弄

于 2021-03-15T09:48:27.597 回答