oracle - 确定是春天还是秋天,如果夏令时调整时间
问题描述
我有一个这样的查询:
SELECT
to_date(to_char((from_tz(to_timestamp(to_char(my_column, 'YYYY-MM-DD HH:MI:SS PM'), 'YYYY-MM-DD HH:MI:SS PM') ,'America/Edmonton')at time zone 'America/Vancouver'),'YYYY-MM-DD'),'YYYY-MM-DD') as Date_Column
FROM
my_table
它将 MST 与 PST 之间的时间转换。这在大多数情况下都有效,除非出现夏令时。然后当时钟向前移动一个小时时会发生一种情况,然后由于丢失了一个小时(例如 1:59 到凌晨 3:00),那么我们正试图转换一个虚构的时间。
所以我知道这个问题,并且我知道 Oracle 会因为这个原因抛出这个错误:
ORA-01878: specified field not found in datetime or interval
我已经在互联网上寻找可能的解决方法,但找不到任何可行的方法。我只想修改我的查询,以便它可以知道现在是一年中的什么时间,或者在时间存在时进行对话,或者在时间不存在时以某种方式处理时间。也许在它丢失时添加额外的小时,并在一年中的其他时间删除它。
有人对此有解决方案吗?这是一个不可能的问题吗?
解决方案
而不是您正在使用的所有转换,只需使用AT TIME ZONE
. 根据列的数据类型,您可能需要格外小心。该AT TIME ZONE
功能将始终考虑夏令时。
- 如果您的专栏是 a
TIMESTAMP WITH TIME ZONE
,那将是理想的,因为您可以说AT TIME ZONE 'PST'
,您将获得 PST 的时间。 - 如果该列是 datatype
TIMESTAMP
,当您使用AT TIME ZONE
它时,它将从当前会话的时区转换为您指定的任何时间。 - 如果您的列是 a
DATE
,则需要TIMESTAMP
先将其转换为 a ,然后才能使用该AT TIME ZONE
功能。将 转换DATE
为TIMESTAMP
将使时区 0:00 偏移,因此请务必考虑到这一点。
另一个方便的技巧是使用AT LOCAL
. 这会将时间戳转换为当前会话的时区。如果您的应用程序用户位于多个时区,这可能会很方便。
例子
我在时区 -04:00(美国东海岸),这就是为什么在下面的示例中显示为我的时区。
WITH
my_table
AS
(SELECT TIMESTAMP '2021-01-01 8:00:00 -7:00' AS ts_with_tz,
TIMESTAMP '2021-01-01 8:00:00' AS ts,
DATE '2021-01-01' + (8 / 24) AS dt
FROM DUAL)
SELECT 1 AS example_num,
t.ts_with_tz,
t.ts,
t.dt
FROM my_table t
UNION ALL
SELECT 2 AS example_num,
t.ts_with_tz AT TIME ZONE 'PST',
t.ts AT TIME ZONE 'PST',
TO_TIMESTAMP (t.dt) AT TIME ZONE 'PST'
FROM my_table t
ORDER BY 1;
结果
EXAMPLE_NUM TS_WITH_TZ TS DT
______________ ______________________________________________________ ______________________________________________________ ______________________________________________________
1 01-JAN-21 08.00.00.000000000 AM -07:00 01-JAN-21 08.00.00.000000000 AM AMERICA/NEW_YORK 01-JAN-21 08.00.00.000000000 AM AMERICA/NEW_YORK
2 01-JAN-21 07.00.00.000000000 AM AMERICA/LOS_ANGELES 01-JAN-21 05.00.00.000000000 AM AMERICA/LOS_ANGELES 31-DEC-20 09.00.00.000000000 PM AMERICA/LOS_ANGELES
推荐阅读
- html - Ionic 4 按钮禁用属性
- azure - 运行 Dataflow 时,Azure 数据工厂运行时看起来不同
- html - 使文本区域填充剩余的 td 而不会溢出到新行
- google-apps-script - 为特定工作表创建 CSV 文件,然后发送带有表格的电子邮件(文件名和链接)
- mysql - Apache Superset 无法连接到 MySQL 5.1
- nginx - Nginx 上的 Flask 应用程序在 1 分钟后超时
- java - 以 java 保留字作为包名的弹出 expo 应用程序
- python - 在 python 中,有没有办法设置一个非阻塞的 tkinter 更新计时器,同时保持窗口打开?
- javascript - 我的电梯循环数量做错了什么?
- c - 如果逻辑流,使用夹板检测总是错误的