带有时区的Oracle DateTime查询

时间:2012-01-10 13:34:38

标签: sql oracle ado.net timezone

我有一个直接使用ADO.NET的SQL Builder库。我有一种方法可以使用大于或等于运算符创建一个选择查询,例如:

select *
from book
where book.date_created >= {some date}

我的问题是{some date}将始终位于UTC时区,但它会与book.date_created列进行比较,该列是TIMESTAMP(6)WITH TIME ZONE列,不会出现在UTC时区。

我可以执行查询,但我的结果不是时区比较的结果。我的查询是针对date_created> = x的所有书籍,但返回的一些结果不大于x,因为在减去时区的5小时后,它们现在小于x。返回的IDataRecord DateTime字段使用DateTime.SpecifyKind()

转换为UTC

我可以形成我的查询,以便它解释UTC时区中的book.date_created吗?

注意:虽然我很乐意将Oracle DB列更改为不指定时区,但我无法更改表结构。

编辑: 目前,{some date}是一个SQL参数。它的支持数据类型是以UTC为时区的DateTime。作为参数,它是TimestampWithTZ。参数的值是DateTime,其类型也指定为UTC。

更新: 该问题似乎与我从IDataRecord设置的结果有关。当我关闭DateTimes时,我使用DateTime.SpecifyKind()将它们置于UTC模式。问题是,日期时间是DateTimeKind.Unspecified。从Unspecified转换为UTC时,它只删除时区并声明它是UTC而不更改基础值。我不确定如何让IDataRecord拉入TimeZone值。

2 个答案:

答案 0 :(得分:3)

您需要使用FROM_TZ函数将TIMESTAMP转换为TIMESTAMP WITH TIME ZONE。例如,如果您知道您的变量是UTC时间(+0:00):

SELECT * 
  FROM book 
 WHERE date_created >= from_tz(<timestamp>, '+0:00');

这是一个示例脚本,显示您描述的行为(您的本地时区应设置为+1:00):

CREATE TABLE t (tz TIMESTAMP(6) WITH TIME ZONE);
INSERT INTO t VALUES 
(to_timestamp_tz('20000101 00:00:00 +1:00','yyyymmdd hh24:mi:ss tzh:tzm'));
INSERT INTO t VALUES 
(to_timestamp_tz('20000101 00:00:00 -1:00','yyyymmdd hh24:mi:ss tzh:tzm'));

-- This will return two values instead of one
SELECT * 
  FROM t 
 WHERE tz >= to_timestamp('20000101 00:00:00', 'yyyymmdd hh24:mi:ss');

-- This query will return only one row
SELECT * 
  FROM t 
 WHERE tz >= from_tz (to_timestamp('20000101 00:00:00', 
                                   'yyyymmdd hh24:mi:ss'), '+0:00');

答案 1 :(得分:0)