воскресенье, 21 ноября 2010 г.

Time zone, работа с временными зонами

Недавно понадобилось работать с часовыми поясами: Московское время перевести на Киевское.

Обычно делают так:

alter session set nls_date_format = 'DD.MM.YYYY HH24:MI:SS';

COLUMN kiev_time FORMAT A40

select --Московское время
       to_date('22.11.2010 20:20:20', 'DD.MM.YYYY HH24:MI:SS') - 1 / 24 kiev_time
  from dual;

Session altered.

KIEV_TIME            
---------------------
22.11.2010 19:20:20  
1 row selected.


А вот как с помощью типа TIMESTAMP, полный перечень временных зон в документации:


--Список временных зон
SELECT tzname, tzabbrev FROM V$TIMEZONE_NAMES;

COLUMN kiev_time FORMAT A40

-- С московского времени на киевское
select FROM_TZ(
         CAST(to_date('22.11.2010 20:20:20', 'DD.MM.YYYY HH24:MI:SS') AS TIMESTAMP),
         'Etc/GMT+3'
       ) AT TIME ZONE 'Etc/GMT+2' kiev_time
  from dual;

KIEV_TIME                          
-----------------------------------
22-NOV-10 07.20.20.000000 PM ETC/GM
T+2                                
                                                                                
1 row selected.

COLUMN kiev_time FORMAT A40

-- Полученный TIMESTAMP представить в виде даты(тип DATE)
select CAST(
         FROM_TZ(
           CAST(to_date('22.11.2010 20:20:20', 'DD.MM.YYYY HH24:MI:SS') AS TIMESTAMP),
           'Etc/GMT+3'
         ) AT TIME ZONE 'Etc/GMT+2'
         as DATE) kiev_time
  from dual;

KIEV_TIME                               
----------------------------------------
22.11.2010 19:20:20                     
1 row selected.

В предыдущих примерах использовался GMT, есть другой вариант Europe/Moscow -> Europe/Kiev:

select CAST(
         FROM_TZ(
           CAST(to_date('22.11.2010 20:20:20', 'DD.MM.YYYY HH24:MI:SS') AS TIMESTAMP),
           'Europe/Moscow'
         ) AT TIME ZONE 'Europe/Kiev'
         as DATE) kiev_time
  from dual;

KIEV_TIME            
---------------------
22.11.2010 19:20:20  
1 row selected.


-- Смещение (TZ_OFFSET) следующих временных зон:
select TZ_OFFSET('Europe/Kiev') from dual;

TZ_OFFSET('EUROPE/KIEV')
------------------------
+02:00                  
1 row selected.

select TZ_OFFSET('Europe/Moscow') from dual;

TZ_OFFSET('EUROPE/MOSCOW')
--------------------------
+03:00                    
1 row selected.

-- Текущая временная зона для сессии
SELECT SESSIONTIMEZONE FROM DUAL;

-- Сменить параметр TIME_ZONE для сеанса на Московское
alter session set TIME_ZONE = '+03:00';

select sysdate, current_date, current_timestamp, localtimestamp
 from dual;

Комментариев нет:

Отправить комментарий