Преобразование между java.time.LocalDateTime и java.util.Date
У Java 8 появился совершенно новый API для работы с датой и временем. Одним из самых полезных классов в этом API является LocalDateTime
, который используется для хранения значения даты и времени, не зависящего от часового пояса.
Скорее всего, существует миллионы строк кода, использующих устаревший класс java.util.Date
для этой цели. В связи с этим, при взаимодействии старого и нового кода возникает необходимость преобразования между этими двумя классами. Поскольку не видно прямых методов для выполнения такой операции, как можно осуществить такое преобразование?
5 ответ(ов)
Вот что я придумал (и как и во всех вопросах о дате и времени, это, вероятно, будет опровергнуто из-за каких-то странных настроек часовых поясов, високосных годов или перехода на летнее время 😄).
Обратное преобразование: Date
←-> LocalDateTime
Допустим: Date date = [некоторая дата]
(1) LocalDateTime
< Instant
< Date
Instant instant = Instant.ofEpochMilli(date.getTime());
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
(2) Date
< Instant
< LocalDateTime
Instant instant = ldt.toInstant(ZoneOffset.UTC);
Date date = Date.from(instant);
Пример:
Дано:
Date date = new Date();
System.out.println(date + " long: " + date.getTime());
(1) LocalDateTime
< Instant
< Date
:
Создание Instant
из Date
:
Instant instant = Instant.ofEpochMilli(date.getTime());
System.out.println("Instant из Date:\n" + instant);
Создание Date
из Instant
(необязательно, но для иллюстрации):
date = Date.from(instant);
System.out.println("Date из Instant:\n" + date + " long: " + date.getTime());
Создание LocalDateTime
из Instant
:
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
System.out.println("LocalDateTime из Instant:\n" + ldt);
(2) Date
< Instant
< LocalDateTime
Создание Instant
из LocalDateTime
:
instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println("Instant из LocalDateTime:\n" + instant);
Создание Date
из Instant
:
date = Date.from(instant);
System.out.println("Date из Instant:\n" + date + " long: " + date.getTime());
Результат:
Пт Ноя 01 07:13:04 PDT 2013 long: 1383315184574
Instant из Date:
2013-11-01T14:13:04.574Z
Date из Instant:
Пт Ноя 01 07:13:04 PDT 2013 long: 1383315184574
LocalDateTime из Instant:
2013-11-01T14:13:04.574
Instant из LocalDateTime:
2013-11-01T14:13:04.574Z
Date из Instant:
Пт Ноя 01 07:13:04 PDT 2013 long: 1383315184574
Если вы на100% уверены, что вам нужна временная зона по умолчанию, воспользуйтесь следующим более удобным способом:
Date d = java.sql.Timestamp.valueOf(myLocalDateTime);
Этот метод позволяет создать объект Timestamp
на основе вашего LocalDateTime
. Таким образом, вы избежите дополнительных манипуляций с временными зонами.
Самый быстрый способ преобразования LocalDateTime
в Date
— это использовать следующий код:
Date date = Date.from(ldt.toInstant(ZoneOffset.UTC));
Здесь ldt
— это ваш объект LocalDateTime
. Метод toInstant(ZoneOffset.UTC)
конвертирует LocalDateTime
в Instant
, а Date.from()
создаёт объект Date
из полученного Instant
.
Всё, что вам нужно, находится здесь: http://blog.progs.be/542/date-to-java-time.
Однако ответ о "круговом преобразовании" не совсем точен. Когда вы выполняете следующий код:
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
если ваш системный часовой пояс не установлен на UTC/GMT, вы изменяете время!
Это происходит потому, что LocalDateTime
не хранит информацию о зоне. Когда вы конвертируете Instant
в LocalDateTime
, вы явно задаете часовой пояс UTC, но ваш системный часовой пояс может быть иным. Таким образом, если вы потом попытаетесь скрыть или преобразовать это значение, то получите результаты, которые не соответствуют ожиданиям, так как вы потеряете информацию о моменте времени в UTC. Всегда лучше быть осторожным с преобразованиями между зонами и учитывать текущий часовой пояс приложения.
Для преобразования нового API LocalDateTime
в java.util.Date
можно использовать следующий код:
Date.from(ZonedDateTime.of(time, ZoneId.systemDefault()).toInstant());
Реверсивное преобразование, надеюсь, можно выполнить аналогичным образом.
Надеюсь, это поможет!
Сортировка ArrayList пользовательских объектов по свойству
Как установить Java 8 на Mac
Java 8: Преобразование List<V> в Map<K, V>
Как преобразовать список списков в список в Java 8?
Найти первый элемент по предикату