我需要将数据库生成的日期(列值默认为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。有人可以解释为什么需要这种转换吗?如果有人建议更好的解决方案,我也很感激。
答案 0 :(得分:2)
您可以将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
转换为DATE:
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)
或如果合适,提供硬编码值。
如果任何用户使用其当前本地时区插入/更新任何updated
,则此方法将失败。在这种情况下,时区信息会丢失,无法恢复。
答案 1 :(得分:0)
如果您在任何oracle客户端中运行此查询,您还可以通过运行
更改会话设置ALTER SESSION SET TIME_ZONE =' BST';
当您更改会话time_zone时,来自数据库列的所有日期值和不带时区的时间戳值都将转换为BST。
因此它将确保在公共时区进行比较