Запрос Oracle DateTime с часовыми поясами - PullRequest
4 голосов
/ 10 января 2012

У меня есть библиотека SQL Builder, которая напрямую использует ADO.NET. У меня есть средство для создания запроса выбора с оператором больше или равно, например:

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

Моя проблема в том, что {некоторая дата} всегда будет находиться в часовом поясе UTC, но сравнивается со столбцом book.date_created, который является столбцом TIMESTAMP (6) WITH TIME ZONE, которого не будет в Часовой пояс UTC.

Я могу выполнить запрос, но мои результаты не совпадают из-за сравнения часовых поясов. Мой запрос для всех книг, где date_created> = x, но некоторые возвращаемые результаты не больше x, потому что после вычитания 5 часов для часового пояса они теперь меньше x. Возвращенные поля DateTime IDataRecord преобразуются в UTC с использованием DateTime.SpecifyKind ()

Могу ли я сформировать свой запрос таким образом, чтобы он интерпретировал book.date_created в часовом поясе UTC?

Примечание. Хотя мне бы хотелось изменить столбцы Oracle DB, чтобы они не указывали часовые пояса, изменение структуры таблиц - это не то, что я могу сделать.

Edit: В настоящее время {некоторая дата} является параметром SQL. Он поддерживает тип данных DateTime с UTC в качестве часового пояса. В качестве параметра это TimestampWithTZ. Значением параметра является DateTime с типом, указанным также в формате UTC.

Обновление: Кажется, проблема связана с моим набором результатов из IDataRecord. Когда я отключаю DateTimes, я использую DateTime.SpecifyKind (), чтобы перевести их в режим UTC. Проблема в том, что дата и время появляются как DateTimeKind.Unspecified. При преобразовании из Unspecified в UTC, он просто удаляет часовой пояс и объявляет, что это UTC без изменения базового значения. Я не уверен, как получить IDataRecord в значение TimeZone.

Ответы [ 2 ]

3 голосов
/ 10 января 2012

Вам необходимо использовать функцию 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...