Выбор между java.util.Date или java.sql.Date

Должен ли я использовать java.util.Date или java.sql.Date?

У меня есть база данных VisualFox, и я получил объекты с помощью мастера IntelliJ Idea, используя подходящий драйвер jdbc типа 4.

Идея (или драйвер) создала поля даты как временную метку. Однако поля даты не являются отметками времени, а полями "Дата", они хранят только год, месяц и день.

Так что мне интересно, следует ли мне переключиться на java.util.Date или java.sql.Date. На первый взгляд я думал, что java.sql.Date должен быть подходящим, но он имеет много методов, объявленных как устаревшие.

Ответ 1

Вопрос и другие ответы, похоже, слишком задумываются над этой проблемой. A java.sql.Date - это просто java.util. Дата с установленным временем 00:00:00.

Из java.sql.Date doc (курсив мой текст)...

Дата класса

java.lang.Object

java.util.Date ← Наследует от j.u.Date

java.sql.Date

...

Тонкая обертка вокруг значения миллисекунды, которая позволяет JDBC идентифицировать это как значение DATE SQL. Значение миллисекунды представляет собой миллисекунды, прошедшие с 1 января 1970 года 00: 00: 00.000 GMT. ← Время суток установлено на ноль, полночь GMT/UTC

Чтобы соответствовать определению SQL DATE, значения миллисекунды, обернутые экземпляром java.sql.Date, должны быть "нормализованы", установив часы, минуты, секунды и миллисекунды на ноль в конкретном часовом поясе, с которым экземпляр связан.

Дата-только против даты-времени

Основная проблема:

  • SQL
    В SQL тип данных DATE хранит дату-только, без времени суток.
  • JAVA
    В плохо спроектированной библиотеке с датами, в комплекте с ранними версиями Java, они не включили класс для представления даты.

Вместо создания класса с датой команда Java сделала ужасный взлом. Они взяли свой класс времени (класс java.util.Date, содержащий как дату, так и время) и расширили его, чтобы экземпляр задал свое время от дня до полуночи UTC, 00:00:00. Этот хак, этот подкласс j.u.Date, java.sql.Date.

Все эти взломы, плохой дизайн и неправильное использование сделали путаницу.

Что использовать

Итак, когда использовать какой? Простой, пробив путаницу.

  • При чтении или записи в базу данных столбца с датой только используйте java.sql.Date, поскольку он неуклюже пытается замаскировать свое время суток.
  • Всюду в Java, где вам нужно время в день вместе с вашей датой, используйте java.util.Date.
  • Когда у вас есть java.sql.Date в руке, но вам нужен java.util.Date, просто передайте java.sql.Date. В качестве подкласса java.sql.Date является java.util.Date.

Еще лучше

В современной Java вы знаете, что у вас есть выбор подходящих библиотек времени, чтобы вытеснить старые и печально известные проблемы java.util.Date,.Calendar, SimpleTextFormat и java.sql.Date классы в комплекте с Java. Основные варианты:

Оба предлагают класс LocalDate для представления только даты, без времени и без часовой пояс.

В конце концов драйверы JDBC будут обновлены, чтобы напрямую использовать новые типы данных java.time. Затем мы можем полностью отказаться от уродливого беспорядка, который является классами даты и времени в пакетах java.util. * И java.sql. *.

Модернизированный JDBC

Надеюсь, JDBC будет обновлен, чтобы предоставлять методы getter и setter для java.time LocalDate.

setObject | GetObject

Эта статья, опубликованная Oracle, показывает, что JDBC в Java 8 прозрачно обновлялся, чтобы сопоставить значение SQL DATE с новым java.time.LocalDate, если вы вызываете методы getObject и setObject.

В тупых словах нижняя часть toInstant()

public java.time.LocalDate toLocalDate() public static Date valueOf(java.time.LocalDate)

Часовой пояс

старые классы временив Java (java.util.Date/.Calendar, java.sql.Date/.Timestamp и т.д. до java.time) не имеют часового пояса практически. Некоторые часового пояса глубоко погружены в исходный код, но игнорируются для большинства целей. Наиболее смутно, их методы toString применяют текущий часовой пояс JVM. Поэтому для наивного программиста кажется, что у них есть часовой пояс, но они этого не делают.

Избегать классов времени по дате В java.util. * и java.sql. *

Эта проблема с часовым поясом является одной из многих причин избежать j.u.Date/Calendar и j.sql.Date/Timestamp, когда это возможно. Напишите свою бизнес-логику, используя java.time (Java 8 и более поздние версии). Там, где отсутствует java.time, используйте Joda-Time. Как java.time, так и Joda-Time имеют удобные методы для возврата туда и обратно со старыми классами, где это необходимо.

Ответ 2

В целом, я считаю целесообразным использовать java.util.Date, так как вы можете использовать его в любом месте своей программы, не преобразовывая тип или не загрязняя ваше приложение кодом SQL.

Мне не известно о сценарии, где "java.sql.Date" лучше подходит.

Ответ 4

В соответствии с документом Java рекомендуется использовать соответствующий тип даты в соответствии с базой данных. Однако с Java 8 был предоставлен богатый набор классов в пакете java.time и он должен использоваться, если приложение написано с Java 8.

Класс javaxjava.sql.Date расширяет java.util.Date с незначительными изменениями для контейнера miliseconds, чтобы он мог эффективно поддерживать тип базы данных DATE. Таким образом, мы можем сохранить ввод аннотации @Temporal из класса сущности.

Однако java.util.Date можно использовать для лучшей масштабируемости во всем приложении, чтобы его можно было легко использовать для хранения времени вместе с датой.