Как игнорировать корректировки DST, сделанные java при получении столбца даты из базы данных Oracle? - PullRequest
1 голос
/ 31 мая 2019

У меня есть таблица Oracle с столбцом Дата .

+--------+-----------------------+
|  ID    | CURR_DATE             |       
+--------+-----------------------+                       
|   1    |2003-04-06 02:59:59    |
+--------+-----------------------+  

Когда я делаю

select * from tablename

в консоли базы данных, я получаю правильное значение столбца для CURR_DATE.

Но когда я делаю то же самое из Java-программы, использующей JDBC, время смещается на один час вперед из-за перехода на летнее время. Вот ссылка, которая объясняет это. https://www.timeanddate.com/time/change/usa/new-york?year=2003.

Поэтому я получаю значение 2003-04-06 03: 59: 59 вместо 2003-04-06 02: 59: 59 .

Это происходит потому, что DB и JVM находятся в PST, а PST следует за DST. (Пожалуйста, исправьте меня, если я ошибаюсь)

Вот мой код

String query="select * from tablename";         
PreparedStatement psmt = con.prepareStatement(query);
ResultSet results=psmt.executeQuery();
while(results.next()) {
    System.out.println(results.getString(2));
}

Что можно сделать, чтобы results.getString() вернул мне то же значение, которое есть в базе данных (без каких-либо настроек).

Я хочу вернуть мне исходное значение 2003-04-06 02: 59: 59 вместо скорректированного значения 2003-04-06 03: 59: 59 .

Ответы [ 2 ]

2 голосов
/ 31 мая 2019

Как объяснил @ gord-thompson, вы должны использовать обновленные ojdbc8 или ojdbc10, в идеале 19.3 или 18.3, вы можете использовать их, даже если ваша база данных имеет 11.2g https://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#01_02

results.getObject(2, LocalDateTime.class)

Объяснение

Проблема действительно в реализации класса java.sql.Timestamp. Он представляет миллисекунды с 1970-01-01 00:00:00 по Гринвичу и 2003-04-06 02:59:59 в часовом поясе JVM , 2003-04-06 02:59:59 не существуют в часовом поясе JVM, поэтому анализатор отключен из-за изменения летнего времени.

LocalDateTime не привязан ни к какому часовому поясу и только год-месяц-день-час-минута-секунда-нано и поэтому не имеет проблем, представляющих 2003-04-06 02:59:59 независимо от часового пояса JVM.

1 голос
/ 31 мая 2019

tl; dr

java.time.LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

Использование смарт-объектов, а не немых строк

Вы храните значение даты-времени в столбце даты-времени, поэтому используйте тип даты-времени вДжава.В настоящее время вы используете строки.

Тип Oracle DATE содержит только дату и время суток без какой-либо концепции часового пояса или смещения от UTC.Таким образом, столбец DATE нельзя использовать для представления момента.Эквивалентом в стандартном SQL является TIMESTAMP WITHOUT TIME ZONE.

Например, если строка хранит значение в этом столбце для 23 января этого года в полдень, мы знаем способ узнать, будет ли это полдень в Токио, полдень в Калькутте, полдень в Париже,или полдень в Монреале.Все эти разные полдни происходят в разные моменты, с интервалом в несколько часов.

Подходящий тип в Java для соответствия столбцу Oracle DATE - LocalDateTime.В этом классе также отсутствует понятие часового пояса или смещения от UTC.Так что это не может быть использовано для представления момента.Но когда у вас есть только дата и время суток без зоны / смещения, этот класс для вас.

JDBC 4.2 и более поздних версий требует поддержки прямого обмена java.time объектамис базой данных.

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

Запись данных.

myPreparedStatemen.setObject( … , ldt ) ;

Путем замены объекта Java без какой-либо зоны / смещения на столбец базы данных типов без какой-либо зоны / смещения, у вас будетнет проблем с зоной / смещением .Но следует помнить об ограничениях такого типа значения даты и времени:

  • Ни минуты, ни точки на временной шкале.
  • Неоднозначно, поскольку его можно интерпретировать как любое измножество потенциальных моментов в диапазоне около 26-27 часов (диапазон часовых поясов вокруг земного шара).

Table of date-time types in Java (both modern and legacy) and in standard SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...