将 TIMESTAMP WITH TIME ZONE 与 DATE 进行比较
Comparing TIMESTAMP WITH TIME ZONE to DATE
我需要将数据库生成的日期(列值默认为 SYSDATE)与记录时区的手写时间戳进行比较。这是我正在尝试的比较:
where trunc(updated, 'mi') >= to_timestamp_tz('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR')
我假设转换为 TIMESTAMP WITH TIME ZONE 的字符串应该与 DATE 相当。但是,这仅在数据库位于我自己的时区时才有效。否则,我必须手动将外部时间戳转换为数据库时区。比如我是BST,数据库是EST,就得写:
where trunc(updated, 'mi') >= to_timestamp_tz('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR')
其中04:45 = 10:45 - 6,6是BST和EST的差值。这看起来完全违反直觉,因为原始时间戳已记录在 PST 中,因此输入为 US/Pacific。有人可以解释为什么需要这种转换吗?如果有人提出更好的解决方案,我也将不胜感激。
您可以将 DATE 列转换为 TIMESTAMP WITH TIME ZONE
值,如下所示:
WHERE
FROM_TZ(CAST(TRUNC(updated, 'mi') AS TIMESTAMP),
(SELECT TO_CHAR(SYSTIMESTAMP, 'TZR') FROM dual)) >= to_timestamp_tz('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR')
但反过来也可以,即将 TIMESTAMP WITH TIME ZONE
转换为数据库时区中的日期:
WHERE
TRUNC(updated, 'mi') >=
CAST(TO_TIMESTAMP_TZ('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR') AT TIME ZONE (SELECT TO_CHAR(SYSTIMESTAMP, 'TZR') FROM dual) AS DATE)
SYDATE
是在数据库服务器操作系统的时区中提供的 (NOT DBTIMEZONE
) ,因此您必须使用 (SELECT TO_CHAR(SYSTIMESTAMP, 'TZR') FROM dual)
或在适当时提供硬编码值。
如果任何用户 inserted/updated 任何 updated
使用他当前的本地时区,此方法将失败。在这种情况下,时区信息会丢失并且无法恢复。
如果您在任何 oracle 客户端中 运行 此查询,您还可以通过 运行
更改会话设置
ALTER SESSION SET TIME_ZONE ='BST';
当您更改会话时time_zone所有来自数据库列的日期值和不带时区传递的时间戳值都将转换为 BST。
因此它将确保比较发生在共同时区
我需要将数据库生成的日期(列值默认为 SYSDATE)与记录时区的手写时间戳进行比较。这是我正在尝试的比较:
where trunc(updated, 'mi') >= to_timestamp_tz('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR')
我假设转换为 TIMESTAMP WITH TIME ZONE 的字符串应该与 DATE 相当。但是,这仅在数据库位于我自己的时区时才有效。否则,我必须手动将外部时间戳转换为数据库时区。比如我是BST,数据库是EST,就得写:
where trunc(updated, 'mi') >= to_timestamp_tz('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR')
其中04:45 = 10:45 - 6,6是BST和EST的差值。这看起来完全违反直觉,因为原始时间戳已记录在 PST 中,因此输入为 US/Pacific。有人可以解释为什么需要这种转换吗?如果有人提出更好的解决方案,我也将不胜感激。
您可以将 DATE 列转换为 TIMESTAMP WITH TIME ZONE
值,如下所示:
WHERE
FROM_TZ(CAST(TRUNC(updated, 'mi') AS TIMESTAMP),
(SELECT TO_CHAR(SYSTIMESTAMP, 'TZR') FROM dual)) >= to_timestamp_tz('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR')
但反过来也可以,即将 TIMESTAMP WITH TIME ZONE
转换为数据库时区中的日期:
WHERE
TRUNC(updated, 'mi') >=
CAST(TO_TIMESTAMP_TZ('2017-10-24 04:45 US/Pacific', 'YYYY-MM-DD HH24:mi TZR') AT TIME ZONE (SELECT TO_CHAR(SYSTIMESTAMP, 'TZR') FROM dual) AS DATE)
SYDATE
是在数据库服务器操作系统的时区中提供的 (NOT DBTIMEZONE
) ,因此您必须使用 (SELECT TO_CHAR(SYSTIMESTAMP, 'TZR') FROM dual)
或在适当时提供硬编码值。
如果任何用户 inserted/updated 任何 updated
使用他当前的本地时区,此方法将失败。在这种情况下,时区信息会丢失并且无法恢复。
如果您在任何 oracle 客户端中 运行 此查询,您还可以通过 运行
更改会话设置ALTER SESSION SET TIME_ZONE ='BST';
当您更改会话时time_zone所有来自数据库列的日期值和不带时区传递的时间戳值都将转换为 BST。
因此它将确保比较发生在共同时区