Как отобразить java.time.LocalTime с миллисекундами в java.sql.Time с миллисекундами - PullRequest
0 голосов
/ 05 июля 2018

Как я могу преобразовать java.time.LocalTime с долями секунды (микро / милли / нано) в java.sql.Time?

Я знаю, что начиная с версии 2.x spring-data-jpa эти типы (JSR310) имеют свои собственные конвертеры, которые отображаются на устаревшие java.sql.Date и java.sql.Timestamp, но у меня много проблем с долей секунды часть LocalTime.

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

Основная проблема заключается в том, что местное время представляет собой конкретное время в течение дня:

например. 7:30 pm

Не 7:30 вечера сегодня или вчера или семнадцать недель с воскресенья, просто ... 7:30 вечера.

Принимая во внимание, что java.sql.Time представляет определенное время в определенный день .

Внутренне они хранятся в виде long , который представляет собой количество миллисекунд до или после определенной даты (IIRC 1 января 1970 г.).

Таким образом, чтобы преобразовать LocalTime в java.sql.Time, вы должны указать конкретный день, к которому будет применяться это время.

Посмотрите на LocalTime.atDate (LocalDate), который возвращает LocalDateTime.

Кажется, нет простого способа извлечения миллисекунд или нетто наносекунд (с 01.01.1970 00:00:00)

Возможно, попробуйте .toEpochSecond (требуется указать часовой пояс), затем умножьте его на 1000 или 1000000 и запишите его в БД, а затем прочитайте его обратно (чтобы увидеть, работает ли он).


С другой стороны:

Вы продолжаете говорить, что вам не нужна дата - я понимаю, но поскольку в базе данных этого нет, вы можете попробовать сохранить localTime.toNanoOfDay.

Он будет интерпретировать это как время дня 1 января 1970 года.

0 голосов
/ 05 июля 2018

Вполне возможно, что вы не захотите конвертировать из LocalTime в старомодный Time.

Если вы считаете, что вам нужно java.sql.Time для хранения в базе данных SQL или для запроса к ней, это может быть не так. При условии, что вы можете использовать по крайней мере Java 8 и по крайней мере JDBC 4.2 (или современную реализацию JPA), вы можете использовать ваш LocalTime непосредственно по отношению к базе данных и не нуждаться в преобразовании. Используйте, например,

    yourPreparedStatement.setObject(7, yourLocalTime);

Тогда все будет хорошо.

Если вам нужен java.sql.Time, ответ Андреса показывает правильный и точный способ конвертации. Проблема в том, что простой Time.valueOf(LocalTime) теряет долю секунды. Документы говорят:

Поле наносекунд от LocalTime не является частью вновь созданного объекта Time.

Понятно, что вы не можете иметь все наносекунды, поскольку Time имеет точность только в миллисекундах. Почему они не взяли миллисекунды (первые 3 десятичных знака 9-значного наносекундного значения), я не знаю. Андреас делает.

0 голосов
/ 05 июля 2018

Как сопоставить java.time.LocalTime с java.sql.Time

Вот один из способов сделать это без использования String в качестве промежуточного значения.

java.time.LocalTime localTime = java.time.LocalTime.now();
long epochMilli = localTime.atDate(java.time.LocalDate.EPOCH)
                           .atZone(java.time.ZoneId.systemDefault())
                           .toInstant()
                           .toEpochMilli();
java.sql.Time sqlTime = new java.sql.Time(epochMilli);

System.out.println(localTime.format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS")));
System.out.println(new SimpleDateFormat("HH:mm:ss.SSS").format(sqlTime));

Выход

22:28:22.104
22:28:22.104
...