Oracle SQL: преобразование метки времени в UTC

У меня есть простой запрос выбора, например ниже, но я заметил, что я возвращаюсь в региональные времена. Как я могу конвертировать в UTC в выбранном статусе?

Select myTimeStamp, MyName, MyBranch from tableA

Result: '27/03/2014 15:15:26' 'john', 'london'

Я пробовал использовать sys_extract_utc (myTimeStamp), но ошибка 'sql command неправильно закончилась.

myTimestamp имеет тип 'date'

Ответ 1

select cast(mytimestamp as timestamp) at time zone 'UTC', 
       MyName, 
       MyBranch 
from tableA

Потому что mytimestamp на самом деле является date не меткой времени, которую вам нужно отдать. Это делает Oracle предполагать, что информация, хранящаяся в mytimestamp, находится в часовом поясе сервера. Если это не так, вам нужно использовать решение Madhawas.

Ответ 2

В зависимости от типа существует несколько ошибок в отношении того, какой часовой пояс Oracle преобразует из зависимости от типа данных myTimestamp.

отметка времени с часовым поясом

Это Just Works ™. a_horse_with_no_name имеет правильный ответ здесь.

отметка времени с местным часовым поясом

он неявно отбрасывается в временную метку с часовым поясом, затем он просто работает ™. Опять же, a_horse_with_no_name находится здесь.

Отметка времени

Пока он также неявно отображается в временной отметке с часовым поясом, часовой пояс, который по умолчанию назначается, - это часовой пояс сеанса (в отличие от часовой пояс базы данных).

  • Явным вызовом этого является myTimestamp at local.
  • В качестве альтернативы (и, скорее всего, лучше) вы можете сделать так: Madhawas говорит и использует функцию from_tz для явного создания значения с явным часовым поясом, отличным от сеанса вашей сессии.

Дата

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

  • myTimestamp at time zone 'UTC'
    ORA-30084: недопустимый тип данных для первичного источника данных с модификатором часового пояса

  • from_tz(myTimestamp, 'America/New_York')
    ORA-00932: непоследовательные типы данных: ожидаемый TIMESTAMP получил DATE

Решение состоит в том, чтобы перенести дату на временную метку:

select from_tz(cast(myTimestamp as timestamp), 'America/New_York') from tableA

Пример Script

Ниже приведено описание script. Обратите внимание, что в моей системе dbtimezone - US/Central, а sessiontimezone - GMT-05: 00.

Я также использую to_char для преобразования вывода, поскольку я нашел, что некоторые инструменты изменят временную метку результата тонким образом, особенно если у них нет хорошей поддержки временной отметки (это редко встречается в настоящее время, но все же потенциально может быть проблемой).

alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZR'
/

select dbtimezone
      ,sessiontimezone
      ,to_char(timestamp '2017-01-01 06:00:00') as ts
      ,to_char(timestamp '2017-01-01 06:00:00' at local) as ts_at_local
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone dbtimezone) as ts_at_db
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone sessiontimezone) as ts_at_session
 from dual
/

Выход в моей системе выглядит следующим образом (переформатирован как столбчатый для удобочитаемости):

DBTIMEZONE          US/Central
SESSIONTIMEZONE     -05:00
TS                  2017-01-01 06:00:00
TS_AT_LOCAL         2017-01-01 06:00:00 -05:00
TS_AT_DB            2017-01-01 05:00:00 US/CENTRAL
TS_AT_SESSION       2017-01-01 06:00:00 -05:00

Ответ 3

Для этого вам нужно знать свой часовой пояс;

SELECT myTimeStamp, from_tz(myTimeStamp, 'America/New_York') AT TIME ZONE 'UTC' utc FROM dual;