powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Timestamp with time zone bug?
3 сообщений из 3, страница 1 из 1
Timestamp with time zone bug?
    #40027989
avang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Окружение
БД: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 – Production (dbtimezone = +00:00), стоит отдельно от клиента.
Java клиента: 1.8.0_201
ОС клиента: Windows 10
Зона клиента: MSK

Стек технологий:
org.springframework.boot:spring-boot-starter-parent:2.2.7.RELEASE
spring-boot-starter-data-jpa
org.hibernate:hibernate-core
com.oracle.jdbc:ojdbc8:18.3.0.0

Описание проблемы №1:
В Oracle в колонки с типом timestamp with local time zone и timestamp with time zone сохраняются две даты 2005-10-30T02:00+04:00[Europe/Moscow] и 2005-10-30T02:00+03:00[Europe/Moscow] (2 часа по летнему времени и 2 часа по зимнему времени – перевод часов). Сначала одна в обе колонки, затем другая.
Описанное ниже справедливо как для типа OffsetDateTime так и для ZonedDateTime.

В итоге ОБЕ даты в БД выглядят одинаково.
В столбце с типом with local time zone отображается значение 2005-10-29 23:00:00.000000.
В столбце с типом with time zone отображается значение 2005-10-30 02:00:00.000000 +04:00.
Другими словами, две разные даты после сохранения в Oracle имеют в БД одно значение.
Обе даты после вычитки из БД имеют следующее представление в Java:
для OffsetDateTime: 2005-10-30T02:00+03:00
для ZonedDateTime: 2005-10-30T02:00+03:00[Europe/Moscow]
Вопрос: почему две резные даты (2 часа по летнему и 2 часа по зимнему времени) в Oracle имеют одинаковое представление?
Замечено, что дата 2005-10-30T03:00+03:00[Europe/Moscow] сохраняется корректно и имеет следующее представление в БД:
в столбце с типом with local time zone отображается значение 2005-10-30 00:00:00.000000,
в столбце с типом with time zone отображается значение 2005-10-30 03:00:00.000000 +03:00

Описание проблемы №2
Если в настройках программы выставить параметр: spring.jpa.properties.hibernate.jdbc.time_zone=UTC

При том, что системная зона клиента МСК, то те же даты в Oracle будут иметь следующее представление:
в столбце с типом with local time zone отображаются значения: 2005-10-29 18:00:00.000000 и 2005-10-29 19:00:00.000000 соответственно.
в столбце с типом with time zone отображаются значения 2005-10-29 22:00:00.000000 +04:00 и 2005-10-29 23:00:00.000000 +04:00 соответственно.
Т.е. время было приведено к UTC, но информация о зоне сохранилась. В результате смещение зоны было вычтено дважды, что видно по столбцу с типом timestamp with local time zone.

P.S. В PostgreSql не возникает проблем при сохранении и чтении этих же дат. По этой причине предполагаю, что проблема именно в Oracle и/или его JDBC драйвере.
...
Рейтинг: 0 / 0
Timestamp with time zone bug?
    #40028090
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
avang

В Oracle в колонки с типом timestamp with local time zone и timestamp with time zone сохраняются две даты 2005-10-30T02:00+04:00[Europe/Moscow] и 2005-10-30T02:00+03:00[Europe/Moscow]

Начните с простого.
Что конкретно означают Ваши даты?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
SQL> select to_timestamp_tz('2005-10-30T02:00 Europe/Moscow','YYYY-MM-DD"T"HH24:MI TZR', q'{NLS_DATE_LANGUAGE='AMERICAN'}')
  2  from dual
  3  ;
 
TO_TIMESTAMP_TZ('2005-10-30T02
-------------------------------------------------
30-OCT-05 02.00.00.000000000 AM EUROPE/MOSCOW

SQL> select to_timestamp_tz('2005-10-30T02:00 +04:00','YYYY-MM-DD"T"HH24:MI TZH:TZM', q'{NLS_DATE_LANGUAGE='AMERICAN'}')
  2  from dual
  3  ;
 
TO_TIMESTAMP_TZ('2005-10-30T02
-------------------------------------------------
30-OCT-05 02.00.00.000000000 AM +04:00

SQL> select to_timestamp_tz('2005-10-30T02:00 +04:00 Europe/Moscow','YYYY-MM-DD"T"HH24:MI TZH:TZM TZR', q'{NLS_DATE_LANGUAGE='AMERICAN'}')
  2  from dual
  3  ;
 
select to_timestamp_tz('2005-10-30T02:00 +04:00 Europe/Moscow','YYYY-MM-DD"T"HH24:MI TZH:TZM TZR', q'{NLS_DATE_LANGUAGE='AMERICAN'}')
from dual
 
ORA-01857: not a valid time zone
 
SQL> 
...
Рейтинг: 0 / 0
Timestamp with time zone bug?
    #40028349
avang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous,
andrey_anonymousЧто конкретно означают Ваши даты?
Я чрез hibernate и тип ZonedDateTime (OffsetDateTime) сохранил в БД Oracle две даты.
Первая 2005-10-30T02:00+04:00 - два часа ночи по летнему времени,
вторая 2005-10-30T02:00+03:00 - два часа ночи по зимнему времени (после перевода стрелок на час назад).
Потом сделал select к таблице в которую сохранил даты.

Таблица создана скриптом:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
create table tmp(
    id long,
    ts1 timestamp,
    ts2 timestamp,
    tsltz1 timestamp with local time zone,
    tsltz2 timestamp with local time zone,
    tstz1 timestamp with time zone,
    tstz2 timestamp with time zone
);


В первые колонки сохранялся OffsetDateTime, во вторые ZonedDateTime.

Одна запись в БД - одна дата во всех колонках.

Запрос к таблице:
Код: plsql
1.
select * from tmp;



В итоге получаю следующий результат:
Код: plsql
1.
2.
1	2005-10-30 02:00:00.000000	2005-10-30 02:00:00.000000	2005-10-29 23:00:00.000000	2005-10-29 23:00:00.000000	2005-10-30 02:00:00.000000 +04:00	2005-10-30 02:00:00.000000 +04:00
2	2005-10-30 02:00:00.000000	2005-10-30 02:00:00.000000	2005-10-29 23:00:00.000000	2005-10-29 23:00:00.000000	2005-10-30 02:00:00.000000 +04:00	2005-10-30 02:00:00.000000 +04:00



Данные выводятся в порядке объявления полей в таблице tmp.
Как можно заметить данные не отличаются.

В Java даты создаю следующим образом:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Date dt2 = new Date(1130623200000L); //+4
Date dt3 = new Date(1130626800000L); //+3
ZonedDateTime zdt2 = ZonedDateTime.ofInstant(dt2.toInstant(), ZoneId.systemDefault());
ZonedDateTime zdt3 = ZonedDateTime.ofInstant(dt3.toInstant(), ZoneId.systemDefault());
OffsetDateTime odt2 = zdt2.toOffsetDateTime();
OffsetDateTime odt3 = zdt3.toOffsetDateTime();

DateTimeOracle dt = new DateTimeOracle(); // entity, соответствующая таблице tmp;
dt.setId(1L);
dt.setTs1(odt2);
dt.setTs2(zdt2);
dt.setTsltz1(odt2);
dt.setTsltz2(zdt2);
dt.setTstz1(odt2);
dt.setTstz2(zdt2);

em.getTransaction().begin();
em.persist(dt);
em.flush();
em.getTransaction().commit();

// аналогично для второй даты - инициирую поля значениями odt3 и zdt3
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Timestamp with time zone bug?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]