Ошибка перехода на летнее время

Я хотел бы рассчитать разницу во времени между датами в другом часовом поясе. Я дважды конвертирую это время в гринвичское время. Но когда я конвертирую даты в часовой пояс Europe/Moscow, смещение другое, хотя летнего времени нет.

Это тот случай, который я проверил:

SELECT TO_DATE('5/20/2018 10:05:00 PM','mm/dd/yyyy hh:mi:ss am'),
       TO_DATE('5/20/2018 10:05:00 PM','mm/dd/yyyy hh:mi:ss am') 
             - extract(TIMEZONE_HOUR from from_tz (TO_TIMESTAMP('5/20/2018 10:05:00 PM','mm/dd/yyyy hh:mi:ss am') ,'GMT' ) at time zone 'Europe/Moscow')/24 deptime_GRINICH
from dual
UNION
SELECT TO_DATE('5/24/2018 11:35:00 PM','mm/dd/yyyy hh:mi:ss am'),
       TO_DATE('5/24/2018 11:35:00 PM','mm/dd/yyyy hh:mi:ss am') 
             - extract(TIMEZONE_HOUR from  from_tz (TO_TIMESTAMP('5/24/2018 11:35:00 PM','mm/dd/yyyy hh:mi:ss am') ,'GMT' ) at time zone 'Europe/Moscow')/24 deptime_GRINICH
from dual

И вот результаты:

Date                         date converting to Greenwich time zone
5/20/2018 10:05:00 PM        5/20/2018 6:05:00 PM   --> hour difference  4 hours
5/24/2018 7:35:00 PM         5/24/2018 3:35:00 PM   --> hour difference  4 hours

но часовые пояса 2018 года - Сочи - это UTC + 3 часа


person Yael Levani    schedule 24.04.2018    source источник
comment
Похоже, вы используете старый файл данных часового пояса, который не знает, что летнее время не применяется. Что сообщает SELECT version FROM v$timezone_file? (Подробнее см. Примечание MoS 412160.1; похоже, это изменение было в версии 23).   -  person Alex Poole    schedule 24.04.2018


Ответы (1)


В октябре 2014 года в России изменились правила перехода на летнее время. Ваш файл часовых поясов в Oracle Database может быть старым, не охватывающим последние изменения. Проверить версию с помощью

SELECT * FROM V$TIMEZONE_FILE;

и рассмотрите возможность обновления, см. Обновление файла часового пояса и метки времени с указанием часового пояса Данные

Однако, похоже, это ошибка в Oracle. Взгляните на мой запрос, который немного понятнее, чем ваш пример:

SELECT *
FROM NLS_SESSION_PARAMETERS
WHERE parameter LIKE 'NLS_TIMESTAMP_TZ_FORMAT';

PARAMETER                  VALUE                  
-------------------------- --------------------------------------
NLS_TIMESTAMP_TZ_FORMAT    YYYY-MM-DD HH24:MI:SSfmXFF3 fmTZH:TZM                                      

1 row selected.


SELECT 
    EXTRACT(TIMEZONE_HOUR FROM TIMESTAMP '2018-05-20 22:05:00 Europe/Moscow') AS TZ_HOUR, 
    TO_CHAR(TIMESTAMP '2018-05-20 22:05:00 Europe/Moscow', 'YYYY-MM-DD HH24:MI:SS TZH:TZM') AS ts2,
    TIMESTAMP '2018-05-20 22:05:00 Europe/Moscow' AS ts3
FROM dual;

   TZ_HOUR TS2                            TS3            
---------- ------------------------------ ----------------------------------
         4 2018-05-20 22:05:00 +04:00     20.05.2018 22:05:00.000000000 +03:00        

1 row selected.

Это действительно странно, потому что TZH:TZM, соотв. EXTRACT(TIMEZONE_HOUR FROM ...) возвращает значение, отличное от значения по умолчанию NLS_TIMESTAMP_TZ_FORMAT = ... TZH:TZM. Для других часовых поясов (например, Europe/Zurich) я всегда получаю 02:00 - как и ожидалось.

Вы можете открыть заявку в службе поддержки Oracle.

У меня две базы данных, старая и новая. Старый не отражает недавних изменений в переходе на летнее время в России, новый - нет. Однако указанная выше ошибка появляется на обоих:

ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZH:TZM';

SELECT filename, VERSION,
    TO_CHAR(TIMESTAMP '2018-05-20 22:05:00 Europe/Moscow', 'TZH:TZM TZD') AS ts1,
    TIMESTAMP '2018-05-20 22:05:00 Europe/Moscow' AS ts2,
    TO_CHAR(TIMESTAMP '2018-01-20 22:05:00 Europe/Moscow', 'TZH:TZM TZD') AS ts3,
    TIMESTAMP '2018-01-20 22:05:00 Europe/Moscow' AS ts4
FROM V$TIMEZONE_FILE;



Old (Daylight-Saving times still existing due to old timezlrg_14.dat file):

FILENAME          VERSION  TS1          TS2                                    TS3           TS4
----------------  -------- -----------  ------------------------------------   -----------   -------------------------------------
timezlrg_14.dat   14       +04:00 MSD   20.05.2018 22:05:00.000000000 +03:00   +03:00 MSK    20.01.2018 22:05:00.000000000 +03:00

New (no Daylight-Saving time changes):

FILENAME          VERSION  TS1          TS2                                    TS3           TS4
----------------  -------- -----------  ------------------------------------   -----------   -------------------------------------
timezlrg_18.dat   18       +04:00 MSK   20.05.2018 22:05:00.000000000 +03:00   +04:00 MSK    20.01.2018 22:05:00.000000000 +03:00
person Wernfried Domscheit    schedule 24.04.2018