Преобразование java.util.Date в java.time.LocalDate
Как лучше всего преобразовать объект java.util.Date
в новый класс JDK 8/JSR-310 java.time.LocalDate
?
Date input = new Date();
LocalDate date = ???
5 ответ(ов)
Более лучший способ:
Date date = ...;
Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
Преимущества этой версии:
- Работает независимо от того, является ли входное значение экземпляром
java.util.Date
или его подклассомjava.sql.Date
(в отличие от подхода @JodaStephen). Это распространённая ситуация с данными, полученными через JDBC. Методjava.sql.Date.toInstant()
всегда выбрасывает исключение. - Один и тот же код работает как в JDK8, так и в JDK7 с бэктпортом JSR-310.
Лично я использую утилитный класс (но он не совместим с бэктпортом):
/**
* Утилиты для преобразования между старыми и новыми типами дат в JDK
* (между {@code java.util.Date} и {@code java.time.*}).
*
* <p>
* Все методы безопасны для null.
*/
public class DateConvertUtils {
// ... остальные методы
/**
* Создает {@link LocalDate} из {@code java.util.Date} или его подклассов. Безопасно для null.
*/
public static LocalDate asLocalDate(java.util.Date date, ZoneId zone) {
if (date == null)
return null;
if (date instanceof java.sql.Date)
return ((java.sql.Date) date).toLocalDate();
else
return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDate();
}
// ... другие методы
}
Метод asLocalDate()
здесь безопасен для null, использует toLocalDate()
, если входные данные — это java.sql.Date
(что может быть переопределено драйвером JDBC, чтобы избежать проблем с временными зонами или ненужными вычислениями), в противном случае используется вышеупомянутый метод.
Ваш код создает объект LocalDate
из объекта Date
, используя формат даты, заданный SimpleDateFormat
. Однако в данном случае вы можете упростить процесс, избегая лишнего преобразования через String
. Вместо этого лучше воспользоваться классом Instant
для преобразования Date
в LocalDate
. Вот как это можно сделать:
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
Date date = ...; // ваша дата
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Этот подход напрямую преобразует объект Date
в LocalDate
, что более эффективно и читабельно.
Вы можете преобразовать объект java.sql.Date
в LocalDate
, используя метод toLocalDate()
. Вот пример кода, который демонстрирует это:
LocalDate ld = new java.sql.Date(new java.util.Date().getTime()).toLocalDate();
В этом коде мы создаем новый объект java.sql.Date
, используя текущее время, полученное через java.util.Date().getTime()
. Затем, применяя метод toLocalDate()
, мы получаем объект LocalDate
, который представляет ту же дату.
Обратите внимание, что использование java.sql.Date
может быть излишним в современных приложениях, так как вы можете сразу работать с LocalDate
, исключая необходимость в промежуточном преобразовании через java.sql.Date
. Лучше воспользоваться LocalDate.now()
, который предоставляет текущее значение LocalDate
напрямую:
LocalDate ld = LocalDate.now();
Этот способ предпочтительнее, так как он проще и более читаем.
Вы можете выполнить преобразование в одну строку следующим образом:
public static LocalDate getLocalDateFromDate(Date date) {
return LocalDate.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
Этот метод сначала преобразует объект Date
в Instant
, а затем использует LocalDate.ofInstant()
, чтобы получить LocalDate
с учетом часового пояса системы.
Сначала, легко конвертировать Date
в Instant
следующим образом:
Instant timestamp = new Date().toInstant();
Затем, вы можете преобразовать Instant
в любой другой объект даты в JDK 8, используя метод ofInstant()
:
LocalDateTime date = LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault());
Эти шаги позволят вам работать с временем в более современных форматах, поддерживаемых Java 8 и выше.
Преобразование между java.time.LocalDateTime и java.util.Date
В чем разница между Instant и LocalDateTime?
Java 8: Преобразование List<V> в Map<K, V>
Почему не стоит использовать Optional в аргументах в Java 8?
Почему компилятор Java 11 использует invokevirtual для вызова приватных методов?