Должен ли я использовать 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
и другие.