Ответ 1
TL;DR
Как преобразовать java.util.Date в java.sql.Date?
Не. Оба класса устарели.
- Используйте классы java.time вместо устаревших
java.util.Date
&java.sql.Date
с JDBC 4.2 или более поздней версии. - Преобразуйте в/из java.time, если взаимодействует с кодом, еще не обновленным до java.time.
Пример запроса с PreparedStatement
.
myPreparedStatement.setObject(
… , // Specify the ordinal number of which argument in SQL statement.
myJavaUtilDate.toInstant() // Convert from legacy class 'java.util.Date' (a moment in UTC) to a modern 'java.time.Instant' (a moment in UTC).
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust from UTC to a particular time zone, to determine a date. Instantiating a 'ZonedDateTime'.
.toLocalDate() // Extract a date-only 'java.time.LocalDate' object from the date-time 'ZonedDateTime' object.
)
Замены:
Instant
вместоjava.util.Date
Оба представляют момент в UTC. но теперь с наносекундами вместо миллисекунд.LocalDate
вместоjava.sql.Date
Оба представляют значение только для даты без времени суток и без часового пояса.
Подробнее
Если вы пытаетесь работать со значениями только по дате (без времени суток, без часового пояса), используйте класс LocalDate
вместо java.util.Date
.
java.time
В Java 8 и более поздних версиях старые проблемные классы даты и времени, связанные с ранними версиями Java, были заменены новым пакетом java.time. См. Учебное пособие по Oracle. Большая часть функциональности была перенесена на Java 6 & 7 в ThreeTen-Backport и дополнительно адаптированы для Android в ThreeTenABP.
Тип данных SQL DATE
предназначен только для даты, без времени суток и часового пояса. У Java никогда не было именно такого класса † до java.time.LocalDate
в Java 8. Давайте создадим такое значение, получая сегодняшнюю дату в соответствии с конкретным часовым поясом (часовой пояс важен при определении даты как нового дня). например, в Париже рассветает раньше, чем в Монреале).
LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) ); // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".
На этом мы можем закончить. Если ваш драйвер JDBC соответствует спецификации JDBC 4.2, вы сможете передавать LocalDate
через setObject
на PreparedStatement
для хранения в поле SQL DATE.
myPreparedStatement.setObject( 1 , localDate );
Аналогично, используйте ResultSet::getObject
для извлечения из столбца SQL DATE в объект Java LocalDate
. Указание класса во втором аргументе делает ваш код безопасным с точки зрения типа.
LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );
Другими словами, весь этот Вопрос не имеет отношения к JDBC 4.2 или более поздней версии.
Если ваш драйвер JDBC не работает таким образом, вам нужно вернуться к преобразованию в типы java.sql.
Конвертировать в java.sql.Date
Для преобразования используйте новые методы, добавленные к старым классам даты и времени. Мы можем вызвать java.sql.Date.valueOf(…)
для преобразования LocalDate
.
java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );
И идти в другом направлении.
LocalDate localDate = sqlDate.toLocalDate();
Преобразование из java.util.Date
Хотя вам следует избегать использования старых классов даты и времени, вас могут заставить работать с существующим кодом. Если это так, вы можете конвертировать в/из java.time.
Пройдите через класс Instant
, который представляет момент на временной шкале в UTC. Instant
по идее аналогичен java.util.Date
. Но обратите внимание, что Instant
имеет разрешение до наносекунд, тогда как java.util.Date
имеет разрешение только миллисекунд.
Для преобразования используйте новые методы, добавленные к старым классам. Например, java.util.Date.from( Instant )
и java.util.Date::toInstant
.
Instant instant = myUtilDate.toInstant();
Чтобы определить дату, нам нужен контекст часового пояса. В любой момент времени дата меняется по всему земному шару в зависимости от часового пояса. Примените ZoneId
, чтобы получить ZonedDateTime
.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();
† Класс java.sql.Date претендует на то, чтобы иметь только дату без времени суток, но фактически делает время суток, настроенное на полночь. Смешение? Да, старые классы даты и времени - беспорядок.
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые legacy унаследованные классы даты и времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, который теперь находится в режиме обслуживания maintenance mode, рекомендует выполнить переход на классы java.time.
Чтобы узнать больше, см. Oracle Tutorial. И поищите в Кару множество примеров и объяснений. Спецификация: JSR 310.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в классах java.sql.*
.
Где взять классы java.time?
- Java SE 8, Java SE 9, Java SE 10 и более поздние
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональности java.time перенесена на Java 6 & 7 в ThreeTen-Backport.
- Android
- Более поздние версии Android связывают реализации классов java.time.
- Для более ранней версии Android (& lt; 26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP….
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и и другие.