简体   繁体   English

带有时区的Oracle DateTime查询

[英]Oracle DateTime query with time zones

I have a SQL Builder library that direcltly uses ADO.NET. 我有一个直接使用ADO.NET的SQL Builder库。 I have a means of creating a select query with a greater-than-or-equal operator, like: 我有一种方法可以使用大于或等于运算符创建选择查询,例如:

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

My issue is that {some date} is going to always be in the UTC time zone, but it's being compared to the book.date_created column which is a TIMESTAMP(6) WITH TIME ZONE column, which will not be in the UTC timezone. 我的问题是{some date}将始终位于UTC时区,但它将与book.date_created列进行比较,该列是TIMESTAMP(6)WITH TIME ZONE列,不在UTC时区。

I can execute the query, but my results are off becuaes of timezone comparisons. 我可以执行查询,但我的结果是时区比较的结果。 My query is for all books where the date_created >= x, but some of the results returned are not greater than x because after subtracting 5 hours for the time zone, they are now less than x. 我的查询是针对date_created> = x的所有书籍,但返回的一些结果不大于x,因为在减去时区的5小时后,它们现在小于x。 The IDataRecord DateTime fields returned are converted to UTC using DateTime.SpecifyKind() 返回的IDataRecord DateTime字段使用DateTime.SpecifyKind()转换为UTC

Can I form my query such that it interprets book.date_created in the UTC timezone? 我可以形成我的查询,以便它解释UTC时区中的book.date_created吗?

Note: While I'd love to change my Oracle DB columns to not specify timezones, changing table structures is not something I can do. 注意:虽然我想更改我的Oracle数据库列而不指定时区,但更改表结构不是我能做的。

Edit: Currently, {some date} is a SQL Parameter. 编辑:目前,{some date}是一个SQL参数。 It's backing datatype is a DateTime with UTC as the timezone. 它的支持数据类型是以UTC为时区的DateTime。 As a parameter, it is a TimestampWithTZ. 作为参数,它是TimestampWithTZ。 The Value of the parameter is a DateTime with the kind specified as UTC as well. 参数的值是DateTime,其类型也指定为UTC。

Update: The issue seems to be related to my results set from the IDataRecord. 更新:该问题似乎与我从IDataRecord设置的结果有关。 When I pull DateTimes off, I use DateTime.SpecifyKind() to put them in UTC mode. 当我关闭DateTimes时,我使用DateTime.SpecifyKind()将它们置于UTC模式。 The problem is, the date times come out as DateTimeKind.Unspecified. 问题是,日期时间是DateTimeKind.Unspecified。 When converting from Unspecified to UTC, it just drops the timezone and declares it is UTC without changing the underlying value. 从Unspecified转换为UTC时,它只删除时区并声明它是UTC而不更改基础值。 I'm not sure how to have the IDataRecord pull in the TimeZone value. 我不确定如何让IDataRecord拉入TimeZone值。

You need to use the FROM_TZ function that transforms a TIMESTAMP into a TIMESTAMP WITH TIME ZONE. 您需要使用FROM_TZ函数将TIMESTAMP转换为TIMESTAMP WITH TIME ZONE。 For example, if you know that your variable is in UTC time (+0:00): 例如,如果您知道您的变量是UTC时间(+0:00):

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

Here's a sample script that shows the behaviour you describe (your local time zone should be set to +1: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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM