Должен ли я использовать java.util.Date или переключиться на java.time.LocalDate

Редактировать: Ну, по-видимому, это было слишком основано на мнениях, поэтому позвольте мне попытаться переформулировать его более точно -

Есть ли какие-либо явные предостережения или недостатки использования LocalDate, LocalTime и т.д. в Java-коде, который не требует обратной совместимости, и если да, то какие они?

Я ищу такие вещи, как "Текущие библиотеки EE X и Y не работают корректно с LocalDate" или "Этот очень полезный шаблон разбит на LocalTime" и так далее.


(вот исходный вопрос для справки)

С Java 8 вводится новый API времени, а именно java.time.LocalDate и т.д., но java.util.Date не помечен как устаревший.

Я пишу новый проект, который не требует обратной совместимости. Должен ли я использовать только LocalDate, LocalDateTime и т.д.? Есть ли недостатки в использовании этого нового API в отличие от старого старого java.util.Date?

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

Поиск дал множество сайтов, рассказывающих о том, как конвертировать из одного формата в другой, но окончательного ответа на то, должен ли новый код использовать старый API.

Спасибо.

Ответы

Ответ 1

Несмотря на имя, java.util.Date может использоваться для хранения как даты, так и времени (он хранит миллисекунды UTC с эпохи)

Я бы определенно использовал новый API из-за больших возможностей:

  • Простой формат/синтаксический анализ. API имеет свои собственные методы форматирования/разбора.
  • API включает в себя операцию добавления/вычитания (минусMinutes, plusDays и т.д.)

Ничего из вышеперечисленного не доступно на java.util.Date

Старая дата также может быть преобразована в LocalDateTime следующим образом:

Date oldDate = ...
LocalDateTime newDateTime = 
  LocalDateTime.from(Instant.ofEpochMilli(oldDate.getTime()));

Ответ 2

Java 8 и более поздние версии: не беспокойтесь

Нет, нет никаких причин, по которым вам не следует использовать java.time, современный API даты и времени Java, если вы используете Java 8 или более позднюю версию (где она встроена).

Единственное, что можно кратко рассмотреть, это то, что вы уже исключили.

Я пишу новый проект, который не должен быть обратно совместимым.

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

Java 6 и 7: весить

Если вы используете Java 6 или 7, вам нужно будет использовать ThreeTen- Backport для java.time, дополнительно адаптированный для Android ниже API уровня 26 в ThreeTenABP. Если вы выполняете только очень небольшую, очень простую работу с датами и временем, и совместимость с пересылкой почему-то не является проблемой, вы можете подумать, стоит ли это внешней зависимости. Пожалуйста, примите во внимание, что ваша внешняя зависимость - это всего лишь бэкпорт того, что встроено в Java 8 и более поздние версии, настолько надежные и, следовательно, что вам понадобится только до перехода на Java 8 или более позднюю версию. В это время вы можете изменить свой импорт, повторно протестировать и покончить с бэкпортом.

Ваши примеры мыслимых обязательств

Текущие библиотеки EE X и Y не работают правильно с LocalDate

Есть несколько примеров этого, также библиотечные классы в JDK. Мой выбор - использовать java.time в своем собственном коде и конвертировать только перед вызовом в API, который еще не принимает тип java.time. И наоборот, если я получу экземпляр устаревшего класса из API, сначала преобразую его, а для остальных использую java.time.

Этот очень полезный шаблон сломан с LocalTime

Я не знаю такой картины. Напротив, java.time использует шаблоны неизменяемых объектов и фабричный метод, в отличие от большинства старых классов.

Ответ 3

Добавляю к правильному ответу Оле В.В.

JDBC 4.2

В частности - я собираюсь работать в основном с JDBC.

В JDBC 4.2 добавлена поддержка обмена объектами java.time с базой данных. См. PreparedStatement::setObject и ResultSet::getObject.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
myPreparedStatement.setObject( … , today ) ;

Индексирование.

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

По причинам, которые меня избегают, спецификация JDBC не требует поддержки двух наиболее часто используемых классов: Instant и ZonedDateTime. Ваша база данных и драйвер JDBC могут или не могут добавить поддержку для них.

Если нет, вы можете легко конвертировать. Начните с OffsetDateTime, с поддержкой, необходимой в JDBC.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Чтобы увидеть этот момент через часы настенного времени, используемые людьми определенного региона (часового пояса), примените ZoneId чтобы получить объект ZonedDateTime.

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant() ;

Чтобы настроить в UTC, извлеките Instant. Instant всегда в UTC, по определению.

Instant instant = odt.toInstant() ;

Вы можете конвертировать другим способом, чтобы записать в базу данных.

myPreparedStatement.setObject( … , zdt.toOffsetDateTime() ;  // Converting from 'ZonedDateTime' to 'OffsetDateTime'. Same moment, same point on the timeline, different wall-clock time.

…а также:

myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ;  // Converting from 'Instant' to 'OffsetDateTime'. Same moment, same point on the timeline, and even the same offset. 'OffsetDateTime' is a more flexible class with abilities such as (a) applying various offsets and (b) flexible formatting when generating text, while 'Instant' is meant to be a more basic building-block class. 

Обратите внимание на соглашение об именах, используемое в java.time: at, from, to, with и так далее.

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


О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, и SimpleDateFormat.

Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений. Спецификация JSR 310.

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*.

Где взять классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и другие.