【问题标题】:Oracle SQL query statement and conditions with timestamps and ISO dates带有时间戳和 ISO 日期的 Oracle SQL 查询语句和条件
【发布时间】:2015-03-28 10:04:56
【问题描述】:

我需要一个查询,它将根据日期时间条件从 Oracle 数据库中选择记录。示例如下:

SELECT * FROM table_name WHERE [modification_date] >= '2014-01-28T12:00:00Z';

作为日期时间,我使用了 ISO 日期,这是“必须”。在 Oracle XE 数据库中,[modification_date] 列的类型为“Timestamp with time zone”。 现在是我的问题 - 如何将查询中的 ISO 日期转换为对数据库的正确搜索?

我尝试将 to_timestamp_tz 添加到查询语句中。

SELECT * FROM table_name
WHERE MODIFICATION_DATE >= to_timestamp_tz('2014-01-28T00:00:0Z', 'YYYY-MM-DD"T"HH24:MI:SS');

但是得到这个错误:

SQL 错误 [1830] [22008]: ORA-01830: 日期格式图片结束于 转换整个输入字符串

【问题讨论】:

  • [modification_date] 是无效的列名称。另外:'2014-01-28T12:00:00Z' 不是“ISO 日期”。它是一个字符串文字,您需要使用to_timestamp() 来创建正确的时间戳值。
  • 可能是duplicate of this;但是你的 Z 也固定了吗?
  • Oracle 不支持TIMESTAMP'2014-01-28T12:00:00Z' 文字吗?
  • @vanzen - 是的,因为你的 Z 最后。如果已修复,也将其包含在双引号中,但您可能希望将其替换为 UTC 并使用 TZR 模型,或者包含 at time zone utc 子句?
  • 好的,我明白了。查询应如下所示:SELECT * FROM table_name WHERE MODIFICATION_DATE >= to_timestamp_tz('2014-01-28T13:00:0Z', 'YYYY-MM-DD"T"HH24:MI:SS"Z"');

标签: sql oracle datetime oracle11g isodate


【解决方案1】:

基于an earlier question,很容易将 T 和 Z 都视为字符文字,并基本上忽略它们,使用:

to_timestamp_tz('2014-01-28T12:00:0Z', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')

如果您使用to_timestamp_tz() 而不指定时区,那么它默认为您的会话时区,to_timestamp() 也是如此;因此 Zulu/UTC 中指定的时间会丢失该区域信息:

alter session set time_zone = 'America/New_York';
select to_timestamp_tz('2014-01-28T12:00:0Z',
  'YYYY-MM-DD"T"HH24:MI:SS"Z"') from dual;

TO_TIMESTAMP_TZ('2014-01-28T12:00:0Z','YYYY-MM-DD"T"HH24:MI:SS"Z"')
-------------------------------------------------------------------
28-JAN-14 12.00.00.000000000 AMERICA/NEW_YORK                       

您的 12:00 时间在纽约显示为 12:00,而不是 12:00 UTC。

假设您的值始终代表 UTC,更安全的转换是使用 the from_tz() function 明确指定时区:

WHERE MODIFICATION_DATE >= from_tz(to_timestamp('2014-01-28T12:00:0Z',
  'YYYY-MM-DD"T"HH24:MI:SS"Z"'), 'UTC')

这会正确获取 UTC 时间:

alter session set time_zone = 'America/New_York';
select from_tz(to_timestamp('2014-01-28T12:00:0Z',
  'YYYY-MM-DD"T"HH24:MI:SS"Z"'), 'UTC') from dual;

FROM_TZ(TO_TIMESTAMP('2014-01-28T12:00:0Z','YYYY-MM-DD"T"HH24:MI:SS"Z"'),'UTC')
-------------------------------------------------------------------------------
28-JAN-14 12.00.00.000000000 UTC                                                

【讨论】:

  • 你也可以使用to_timestamp_TZ('2014-01-28T12:00:0Z'||'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"TZR')
  • 使用'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM',它将匹配2017-01-10T00:00:00Z2017-01-10T00:00:00+00002017-01-10T00:00:00+00:00
【解决方案2】:

查看to_timestamp_tz 函数。

假设 Z 代表 Zulu/UTC,您可以将 Z 替换为 +00:00 并使用 to_timestamp_tz 函数

SELECT * FROM table_name 
WHERE modification_date >= to_timestamp_tz(replace('2014-01-28T12:00:00z','z','+00:00'),'YYYY-MM-DD"T"hh24:mi:sstzh:tzm')

【讨论】:

  • 您不需要将z 替换为+00:00。使用格式掩码 TZH:TZM 将匹配 z 字符并将时区设置为祖鲁时间 (+00:00)。所以你可以做TO_TIMESTAMP_TZ( :your_isotime, 'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM' )
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多