Смещение часового пояса в оракуле

Используя Oracle 9.2i, мне нужно получить смещение различных дат из одного часового пояса по отношению к другому часовому поясу, ранее я делал это как таковой

select
(TO_DATE('10-Oct-2010 09:00:00','DD-Mon-YYYY HH24:Mi:SS') - 
              TO_DATE(TO_CHAR(FROM_TZ(to_timestamp( '10-Oct-2010 09:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'Australia/Victoria')
                AT TIME ZONE 'Australia/West'        , 'DD-Mon-YYYY HH24:Mi:SS'),'DD-Mon-YYYY HH24:Mi:SS'))
from dual

Который, хотя и немного грязный, отлично работал для моих нужд. Теперь проблема в том, что это, похоже, не учитывает летнее время. Разница во времени между Викторией и Западной Австралией 10 октября на самом деле составляет 3 часа, а не 2 часа (поскольку мой запрос в настоящее время возвращает).

Теперь это странно, так как я думал, что FROM_TZ предназначен для обработки летнего времени. И что еще более странно, если я сравниваю с GMT, я получаю правильные результаты.

select FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'GMT') AT TIME ZONE 'Australia/West'
from dual

FROM_TZ(TO_TIMESTAMP('10-OCT-2 
------------------------------ 
10-OCT-10 08.00.00.000000000 AM AUSTRALIA/WEST 

Правильный

select FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'GMT') AT TIME ZONE 'Australia/Victoria'
from dual

FROM_TZ(TO_TIMESTAMP('10-OCT-2 
------------------------------ 
10-OCT-10 11.00.00.000000000 AM AUSTRALIA/VICTORIA 

Правильный

select FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'Australia/Victoria') AT TIME ZONE 'Australia/West'
from dual

FROM_TZ(TO_TIMESTAMP('10-OCT-2 
------------------------------ 
09-OCT-10 10.00.00.000000000 PM AUSTRALIA/WEST 

Неправильный. 00:00:00 10 октября 2010 г. в Виктории — это 09 октября 2010 г. 21:00 в Западной Австралии.

Так вот вопрос, это баг? или я просто использую это FROM_TZ .. AT TIME ZONE неправильно?

Спасибо.

Обновлять:

Я думаю, что это может быть ошибка в функции TO_CHAR, похоже, она получает неправильное смещение TZ. В то время как FROM_TZ может корректно измениться со времени по Гринвичу на время Виктории, когда вы пытаетесь извлечь из него смещение TZ, оно показывает +10, хотя должно быть +11.

select TO_CHAR(FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'Australia/Victoria'), 'TZH:TZM')
      ,FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'GMT') AT TIME ZONE 'Australia/Victoria'
from dual

TO_CHAR(FROM_TZ(TO_TIMESTAMP('                                              FROM_TZ(TO_TIMESTAMP('10-OCT-2 
--------------------------------------------------------------------------- ------------------------------ 
+10:00                                                                      10-OCT-10 11.00.00.000000000 AM AUSTRALIA/VICTORIA 

person Matthew Watson    schedule 13.10.2010    source источник


Ответы (1)


Насколько я могу судить, TZH и TZM являются сокращенными строками часового пояса, но они не учитывают переход на летнее время. Часовой пояс Виктории +10:00.

Возможно, TZD — это то, что вам нужно.

TZD Информация о переходе на летнее время. Значение TZD представляет собой сокращенную строку часового пояса с информацией о переходе на летнее время.

http://download.oracle.com/docs/cd/B28359_01/olap.111/b28126/dml_commands_1029.htm

select TO_CHAR(FROM_TZ(ts, 'Australia/Victoria'), 'TZH:TZM TZD')
      ,FROM_TZ(ts, 'GMT') AT TIME ZONE 'Australia/Victoria'
from (select to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS')
             as ts
      from dual);

+10:00 EST    10/10/2010 10:00:00.000000000 AM +10:00
person Jeffrey Kemp    schedule 13.10.2010