Преобразование DATE в DATE по времени UTC: sys_extract_utc ведет себя по-разному для sysdate и systimestamp - PullRequest
0 голосов
/ 16 ноября 2018
select sysdate from dual;    
15-NOV-2018 23:09:31

select cast(sysdate as TIMESTAMP) from dual;
15-NOV-18 11.07.47.000000000 PM

select sys_extract_utc(cast(sysdate as TIMESTAMP)) from dual;
15-NOV-18 05.40.35.000000000 PM

Но,

select systimestamp from dual;
15-NOV-18 11.11.16.345959000 PM -08:00

select sys_extract_utc(systimestamp) from dual;
16-NOV-18 07.08.49.772214000 AM

Далее,

select cast(sysdate as TIMESTAMP) at time zone 'UTC' from dual;
15-NOV-18 05.48.11.000000000 PM UTC

Почему sys_extract_utc(cast(sysdate as TIMESTAMP)) отличается от sys_extract_utc(systimestamp) в моем БД?
Время, указанное sys_extract_utc(systimestamp), является правильным временем UTC, кстати.

Моим основным требованием является преобразование данных из таблицы со столбцом DATE в «DATE в часовом поясе UTC» в запросе выбора.Конечно, он не работает (с sys_extract_utc или с at time zone 'UTC'), что, вероятно, по той же причине, по которой вышеприведенное преобразование с sysdate не работает.

В случае, если это помогает, dbtimezone:

SELECT DBTIMEZONE FROM DUAL;
+00:00

1 Ответ

0 голосов
/ 16 ноября 2018

Функция SYS_EXTRACT_UTC работает только со значениями TIMESTAMP WITH TIME ZONE или TIMESTAMP WITH LOCAL TIME ZONE.DATE и TIMESTAMP не содержат никакой информации о часовом поясе, поэтому SYS_EXTRACT_UTC в основном бесполезен для значений DATE или TIMESTAMP.

Когда вы запускаете

SYS_EXTRACT_UTC(CAST(SYSDATE AS TIMESTAMP))

затем Oracle выполняет неявное приведение и фактически выполняет

SYS_EXTRACT_UTC(FROM_TZ(CAST(SYSDATE AS TIMESTAMP), SESSIONTIMEZONE))

SYSDATE и SYSTIMESTAMP возвращает время в часовом поясе операционной системы сервера базы данных ( NOT DBTIMEZONE), тогда как ваша командаиспользует текущий сеанс SESSIONTIMEZONE

Если вы настаиваете на использовании значения DATE, вы можете использовать это:

SYS_EXTRACT_UTC(FROM_TZ(CAST(SYSDATE AS TIMESTAMP), TO_CHAR(SYSTIMESTAMP, 'tzr')))

TO_CHAR(SYSTIMESTAMP, 'tzr') предоставляет вам часовой пояс сервера базы данныхоперационная система.

Просто обратите внимание, очень часто часовой пояс операционной системы сервера базы данных не является регионом, подобным Europe/Zurich, а меняется два раза в год между +01:00 и +02:00 из-за перехода на летнее время.Для SYSDATE и SYSTIMESTAMP это не имеет значения, поскольку смещение current UTC всегда корректно.Но, например, если моя таблица содержит значение DATE 2018-08-01 12:00:00, вы получите неверный результат, если выполните запрос сверху сегодня в ноябре.

Если ваш сервер баз данных использует летнее время, лучше использовать такой запрос, как

SYS_EXTRACT_UTC(FROM_TZ(CAST({arbitrary DATE value} AS TIMESTAMP), 'Europe/Zurich'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...