воскресенье, 28 августа 2011 г.

Часовые пояса. Time Zones

В отношении базы данных стоит различать 3 часовых пояса
Часовой пояс UTC (Всемирное координированное время, ‘+00:00’)
Часовой пояс базы данных. Функция DBTIMEZONE
Часовой пояс сессии текущего пользователя. Функция SESSIONTIMEZONE.

Oracle рекомендует в качестве часового пояса базы данных использовать UTС вне зависимости от фактического места положения сервера.
Типы данных хранения даты:
Тип данныхДоли секундыЧасовой пояс
DateНетНет
TIMESTAMPДаНет
TIMESTAMP WITH TIME ZONEДаЯвный
TIMESTAMP WITH LOCAL TIME ZONEДаОтносительный

Типы данных DATE и TIMESTAMP не поддерживают различия в часовых поясах. Два других типа данных которые поддерживают различия в часовых поясах – это TIMESTAMP WITH TIME ZONE и TIMESTAMP WITH LOCAL TIME ZONE.

Oracle поддерживает два типа указания часового пояса:
• Смещение относительно UTC, например ‘+03:00’
• Указание географического региона.

Список доступных географических регионов можно смотреть здесь:
SELECT * FROM V$TIMEZONE_NAMES ORDER BY 1
При использовании названий региона будет производится автоматический переход на/с летнее время, согласно указанного региона. При указании часового смещения, например, ‘+03:00’ этого не будет. Поэтому рекомендуется использование географических названий.
SELECT DBTIMEZONE, SESSIONTIMEZONE  FROM DUAL
DBTIMEZONESESSIONTIMEZONE
+00:00+02:00

Согласно этому примеру часовой пояс БД – UTC, часовой пояс сессии пользователя - +02:00 относительно UTC.

Что бы сменить часовой пояс сессии пользователя соответственно
ALTER SESSION SET TIME_ZONE = '+03:00'
или
ALTER SESSION SET TIME_ZONE = 'Europe/Kiev'
Что бы сменить часовой пояс базы данных
ALTER DATABASE SET TIME_ZONE = '+03:00'
DBTIMEZONESESSIONTIMEZONE
+03:00+03:00

Нельзя изменить часовой пояс базы данных если в ней есть хотя бы одна таблица с полем типа TIMESTAMP WITH LOCAL TIME ZONE. Найти все таблицы и где используется этот тип данных можно так:
SELECT OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM DBA_TAB_COLUMNS
where data_type like '%LOCAL TIME_ZONE%'
ORDER BY OWNER, TABLE_NAME, COLUMN_NAME
TIMESTAMP WITH TIME ZONE хранит дату, время с долями секунды (как и TIMESTAMP) и информацию о часовом поясе.

TIMESTAMP WITH LOCAL TIME ZONE хранит дату, время с долями секунды так же как и TIMESTAMP, но преобразованную к UTC. При запросе дата/время преобразовываются к часовому поясу пользователя который запрашивает данные.