【问题标题】:Convert a date from UTC timezone to PST Time zone (including DST factor)将日期从 UTC 时区转换为 PST 时区(包括 DST 因素)
【发布时间】:2021-06-12 11:29:04
【问题描述】:

我想将 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)

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

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

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

【问题讨论】:

  • end_date 在表格中是否有时区? IE。它是在TIMESTAMP WITH TIME ZONE 数据类型中存储为TIMESTAMP '2021-03-15 07:17:16 UTC' 还是在TIMESTAMP 数据类型中存储为TIMESTAMP '2021-03-15 07:17:16'(并且不存储时区)。
  • 不,它没有存储时区,它只是数据类型 TIMESTAMP。

标签: sql oracle datetime to-timestamp


【解决方案1】:

您有 6 小时的时差,所以我假设您与 Asia/Dacca 处于同一时区,并且使用以下方式设置了我的会话:

ALTER SESSION SET TIME_ZONE='Asia/Dacca';

现在,如果我使用数据类型 TIMESTAMP WITH TIME ZONE 创建 table1

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 | | :-------------------- | | 2021 年 3 月 15 日 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 | | :-------------------- | | 2021 年 3 月 14 日 18:17:16 |

这复制了您的问题。

这是因为数据库不知道数据的时区,并且会隐含地假定它与数据库/会话时区相同,我们已将其设置为 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 | | :-------------------- | | 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小提琴here

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 2015-11-25
    • 1970-01-01
    • 2015-02-09
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多