Получить поле даты / времени Oracle как есть в Java java.sql.Timestamp без преобразования в летнее время - PullRequest
0 голосов
/ 19 марта 2019

У меня есть столбец (LOGIN_TIME) в оракуле с типом данных DATE. Я пытаюсь прочитать его как метку времени в Java с использованием JDBC. Одна из строк в моей таблице имеет значение 2006-04-02 02: 00: 01.0 для этого столбца. когда я

выберите LOGIN_TIME, CAST (LOGIN_TIME как TIMESTAMP) из TABLE;

Я вижу, что sql-developer показывает значение как

2006-04-02 02: 00: 01.0

Но когда я получаю значение этого столбца в Java с помощью метода ResultSet.getTimestamp (), я вижу значение как 2006-04-02 03: 00: 01.0.

После долгих поисков я понял, что

  1. Во-первых, 2006-04-02 02: 00: 01.0 является недействительным / потерянным временем, так как после 2006-04-02 01: 59: 00.0 часы щелкают 2006-04-02 03: 00: 00.0 из-за перехода на летнее время.
  2. Типы данных Oracle Date / Timestamp не поддерживают часовые пояса, поэтому Oracle приняла это значение при вставке в БД без жалоб.
  3. Однако, поскольку 02:00:01 является недопустимым временем, Java по умолчанию относится к нему мягко и переводит время в предполагаемое правильное время 03: 00: 01.

Теперь мои вопросы

  1. Почему java принял правильное время как 03:00:01? Зависит ли он от какого-либо часового пояса, если да, какой часовой пояс по умолчанию? Я не думаю, что часовой пояс по умолчанию здесь UTC, потому что

System.out.println (+ rs.getTimestamp (индекс, Calendar.getInstance (TimeZone.getTimeZone ( "UTC"))));

дал мне значение как

2006-04-01 18: 00: 01.0

  1. Как я могу получить значение из Oracle без преобразования DST с помощью JDBC на 2006-04-02 02: 00: 01.0? или получите его как 2006-04-02 03: 00: 01.0 и конвертируйте его обратно в исходное значение оракула 2006-04-02 02: 00: 01.0.

1 Ответ

1 голос
/ 19 марта 2019

Date в Java не хранит часовой пояс. Вместо этого он использует ваш местный часовой пояс для представления значений. Вот почему вы видите разные результаты.

Если вы используете Java 8 и JDBC 4.2, вы можете вместо этого использовать более надежный пакет java.time.*. Это так просто:

LocalDateTime dateTime = rs.getObject(index, LocalDateTime.class);

Если вы хотите преобразовать LocalDateTime в java.util.Date, вы можете сделать это следующим образом:

 Instant instant = dateTime.atZone(ZoneId.systemDefault()).toInstant();
 Date dateFromOld = Date.from(instant);
...