1. Обзор
Начиная с Java 8, у нас есть новый API Date: java.time
.
Однако иногда нам по-прежнему необходимо выполнять преобразования между новым и старым API и работать с представлениями даты из обоих.
2. Преобразование java.util.Date
в java.time.LocalDate
Начнем с преобразования старого представления даты в новое.
Здесь мы можем воспользоваться новым методом toInstant()
, который был добавлен в java.util.Date
в Java 8.
Когда мы преобразовываем объект Instant
, необходимо использовать ZoneId
, потому что объекты Instant
не зависят от часового пояса
— просто точки на временной шкале.
API atZone(ZoneId zone)
из объекта Instant
возвращает ZonedDateTime
, поэтому нам просто нужно извлечь из него LocalDate
с помощью метода toLocalDate()
.
Во-первых, мы используем системный ZoneId
по умолчанию :
public LocalDate convertToLocalDateViaInstant(Date dateToConvert) {
return dateToConvert.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
И похожее решение, но с другим способом создания объекта Instant
— с использованием метода ofEpochMilli()
:
public LocalDate convertToLocalDateViaMilisecond(Date dateToConvert) {
return Instant.ofEpochMilli(dateToConvert.getTime())
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
Прежде чем двигаться дальше, давайте также кратко рассмотрим старый класс java.sql.Date
и то, как его можно также преобразовать в LocalDate
.
Начиная с Java 8, мы можем найти дополнительный метод toLocalDate
()
для java.sql.Date , который также дает нам простой способ преобразования его в java.time.LocalDate
.
В этом случае нам не нужно беспокоиться о часовом поясе:
public LocalDate convertToLocalDateViaSqlDate(Date dateToConvert) {
return new java.sql.Date(dateToConvert.getTime()).toLocalDate();
}
Точно так же мы можем преобразовать старый объект Date
в объект LocalDateTime
. Давайте посмотрим на это дальше.
3. Преобразование java.util.Date
в java.time.LocalDateTime
Чтобы получить экземпляр LocalDateTime
, мы можем аналогичным образом использовать посредник ZonedDateTime,
а затем использовать API toLocalDateTime()
.
Как и раньше, мы можем использовать два возможных решения для получения объекта Instant из
java.util.Date
:
public LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert) {
return dateToConvert.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
}
public LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert) {
return Instant.ofEpochMilli(dateToConvert.getTime())
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
}
Обратите внимание, что для дат до 10 октября 1582 года необходимо настроить Calendar как григорианский календарь и вызвать метод setGregorianChange ():
GregorianCalendar calendar = new GregorianCalendar();
calendar.setGregorianChange(new Date(Long.MIN_VALUE));
Date dateToConvert = calendar.getTime();
И, начиная с Java 8, мы также можем использовать java.sql.Timestamp
для получения LocalDateTime
:
ocalDateTime convertToLocalDateTimeViaSqlTimestamp(Date dateToConvert) {
return new java.sql.Timestamp(
dateToConvert.getTime()).toLocalDateTime();
}
4. Преобразование java.time.LocalDate
в java.util.Date
Теперь, когда мы хорошо понимаем, как преобразовать старое представление данных в новое, давайте посмотрим на преобразование в другом направлении.
Мы обсудим два возможных способа преобразования LocalDate
в Date
.
В первом мы используем новый метод valueOf(LocalDate date)
, предоставленный в объекте java.sql.Date
, который принимает LocalDate
в качестве параметра:
public Date convertToDateViaSqlDate(LocalDate dateToConvert) {
return java.sql.Date.valueOf(dateToConvert);
}
Как мы видим, это легко и интуитивно понятно. Он использует местный часовой пояс для преобразования (все делается скрыто, так что не о чем беспокоиться).
В другом примере Java 8 мы используем объект Instant
, который мы передаем в метод from (Instant Instant) объекта
java.util.Date
: **** ``
public Date convertToDateViaInstant(LocalDate dateToConvert) {
return java.util.Date.from(dateToConvert.atStartOfDay()
.atZone(ZoneId.systemDefault())
.toInstant());
}
Обратите внимание, что здесь мы используем объект Instant
и что нам также нужно позаботиться о часовых поясах при выполнении этого преобразования.
Далее воспользуемся очень похожим решением для преобразования LocalDateTime
в объект Date
.
5. Преобразование java.time.LocalDateTime
в java.util.Date
Самый простой способ получить java.util.Date из
LocalDateTime —
использовать расширение для java.sql.Timestamp,
доступное в Java 8:
public Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) {
return java.sql.Timestamp.valueOf(dateToConvert);
}
Но, конечно, альтернативным решением является использование объекта Instant
, который мы получаем из ZonedDateTime
:
Date convertToDateViaInstant(LocalDateTime dateToConvert) {
return java.util.Date
.from(dateToConvert.atZone(ZoneId.systemDefault())
.toInstant());
}
6. Дополнения для Java 9
В Java 9 доступны новые методы, упрощающие преобразование между java.util.Date
и java.time.LocalDate
или java.time.LocalDateTime
.
LocalDate.ofInstant(Instant Instant, ZoneId zone)
и LocalDateTime.ofInstant(Instant Instant, ZoneId zone)
предоставляют удобные ярлыки:
public LocalDate convertToLocalDate(Date dateToConvert) {
return LocalDate.ofInstant(
dateToConvert.toInstant(), ZoneId.systemDefault());
}
public LocalDateTime convertToLocalDateTime(Date dateToConvert) {
return LocalDateTime.ofInstant(
dateToConvert.toInstant(), ZoneId.systemDefault());
}
7. Заключение
В этой статье мы рассмотрели возможные способы преобразования старого java.util.Date
в новые java.time.LocalDate
и java.time.LocalDateTime
, а также наоборот.
Полная реализация этой статьи доступна на GitHub .