Преобразуйте java.time.LocalDate в тип java.util.Date.

373

Я хочу преобразовать java.time.LocalDateв java.util.Dateтип. Потому что я хочу установить дату JDateChooser. Или есть какой-нибудь выбор даты, который поддерживает java.timeдаты?

Кавинда Гехан
источник
1
Вы читали stackoverflow.com/questions/21242110/… ?
Дакш Шах
2
LGoodDatePicker изначально использует пакет java.time (он же Java 8 time, или JSR-310 . В частности, LGoodDatePicker использует «java.time.LocalDate» для хранения значений даты. Скриншоты и демонстрационная версия находятся на
домашней
Больше ответов можно найти на: LocalDate to java.util.Date и наоборот - простейшее преобразование?
Василий Бурк

Ответы:

561
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

Это предполагает, что ваш выбор даты использует системный часовой пояс по умолчанию для преобразования дат в строки.

Дж. Б. Низет
источник
JB Nizet, возможно, Java 8 находилась на ранней стадии разработки / выпуска, и @ user3509494 как-то ее тестировал.
Расселхофф
2
Можно ли избежать atStartOfDay(), так как это меняет значение даты, насколько я понимаю.
yegor256
1
@JBNizet ваш ответ не имеет большого смысла для меня, поэтому я решил уточнить. Почему бы вам не уточнить это вместо того, чтобы делать бесполезные комментарии?
yegor256
12
Потому что я не понимаю, как и почему это нужно было бы уточнить. 232 человек проголосовали за этот ответ, что делает его ясным. Вы говорите, что atStartOfDay изменяет значение даты. Это не имеет смысла. atStartOfDay делает то, что говорит javadoc: он преобразует LocalDate в LocalDateTime, в тот же день и в начале дня.
JB
2
@cornz Вы уверены, что ваши результаты неверны? Если вы находитесь в Германии, то это может быть связано с 6-минутным 32-секундным сбоем во времени в Германии в апреле 1893 года. См. Timeanddate.com/time/zone/germany/berlin?syear=1850 для некоторых деталей. ,
Дауд ибн Карим
104

Вот вспомогательный класс, который я использую для преобразования новых java.timeклассов в java.util.Dateобъекты и наоборот:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class DateUtils {

  public static Date asDate(LocalDate localDate) {
    return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
  }

  public static Date asDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }

  public static LocalDate asLocalDate(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
  }

  public static LocalDateTime asLocalDateTime(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
  }
}

Отредактировано на основе комментария @Oliv.

Брайс Ронкас
источник
Не использует ZoneId.systemDefault()проблематично, потому что часовые пояса меняются в течение года. Поэтому, если 01 января я нахожусь в часовом поясе -05: 00 (в центре), а затем 01 июля я нахожусь в часовом поясе -06: 00 (в центральное дневное время), это не приведет к неточным результатам из-за перехода на летнее время время?
Джилден
95

Вы можете использовать java.sql.Date.valueOf()метод как:

Date date = java.sql.Date.valueOf(localDate);

Нет необходимости добавлять информацию о времени и часовом поясе здесь, потому что они взяты неявно.
См. LocalDate для java.util.Date и наоборот самое простое преобразование?

Джордж
источник
Это было идеально для меня, поскольку мне нужно было передать LocalDate в SQL. Однако, если ваш форматировщик даты собирается что-то сделать со смещением часового пояса до форматирования даты, вы можете получить один день раньше, в зависимости от местного часового пояса, и в этом случае вам понадобится один из указанных выше вариантов.
Том Диббл
7
java.sql.Dateпредназначен для уровня базы данных, JDBC, JPA. Веб-слой (или любое клиентское приложение) должен быть абсолютно свободен от какой-либо зависимости java.sql.*.
Tiny
2
@Tiny java.sql.Date находится в rt.jar. Нет никаких внешних зависимостей. Вы просто используете языковые функции.
Джордж
2
java.sql.Dateвремя просто java.util.Dateустановлено, 00:00:00но с точки зрения дизайна, java.sql.*он не предназначен для переднего уровня, с которым взаимодействуют клиенты, такие как Servlets / JSP. java.util.Dateна стороне Java и ( java.sql.Timestampили) java.sql.*на стороне JDBC .
Крошечный
5
Это "ужасный взлом" по версии java.time. * Author: stackoverflow.com/questions/33066904/… . В Java 9 java.sql.*классы будут отдельной зависимостью.
Дерик
16

java.time имеет интерфейс Temporal, который вы можете использовать для создания объектов Instant из большинства классов времени. Мгновенный представляет миллисекунды на временной шкале в эпоху - базовую ссылку для всех других дат и времени.

Нам нужно преобразовать дату в ZonedDateTime с указанием времени и зоны, чтобы выполнить преобразование:

LocalDate ldate = ...;
Instant instant = Instant.from(ldate.atStartOfDay(ZoneId.of("GMT")));
Date date = Date.from(instant);
Кевин Садлер
источник
12

Для того чтобы создать java.util.Date из java.time.LocalDate , вы должны

  • добавить время в LocalDate
  • интерпретировать дату и время в пределах часового пояса
  • получить количество секунд / миллисекунд с начала эпохи
  • создать java.util.Date

Код может выглядеть следующим образом:

LocalDate localDate = LocalDate.now();
Date date = new Date(localDate.atStartOfDay(ZoneId.of("America/New_York")).toEpochSecond() * 1000);
nosid
источник
1
Опечатка в зоне ID (ZoneIf)
assylias
localDate.atStartOfDay () создает ZonedDateTime, но для ZonedDateTime нет метода toEpochSecond ().
Кевин Садлер
@KevinSadler: метод toEpochSecondунаследован от java.time.chrono.ChronoZonedDateTime. См. Docs.oracle.com/javase/8/docs/api/java/time/chrono/…
nosid
@nosid Спасибо за исправление. Когда я использую завершение кода в Eclipse, его (и toInstance) нет в качестве опции. Но если я наберу его в полном объеме, кажется, будет принято. Я ошибочно заключил, что это не метод из-за этого факта, и что я не видел его в Javadoc для ZonedDateTime, так как он указан как унаследованный метод, как вы говорите. Извините, пожалуйста, примите upclick :)
Кевин Садлер
11

Это работает для меня:

java.util.Date d = new SimpleDateFormat("yyyy-MM-dd").parse(localDate.toString());

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#toString--

ceklock
источник
6
это довольно неэффективно
AndresQ
1
Преобразование в Instant может быть многословным, но создание и разбор строки - это все равно, что ехать из Нью-Йорка в Мехико через Токио ...
ehecatl
1
Да, не так эффективно, но большинство решений очень многословны. Это просто многословно, и его легче читать и понимать.
ceklock
2
@ehecatl Остерегайтесь ... в будущем Нью-Йорк -> Токио -> Мехико может быть сделано в течение часа (ов);)
Стефан
3

Котлин Решение:

1) Вставьте эту функцию расширения куда-нибудь.

fun LocalDate.toDate(): Date = Date.from(this.atStartOfDay(ZoneId.systemDefault()).toInstant())

2) Используйте его, и никогда не гуглите это снова.

val myDate = myLocalDate.toDate()
GYODER
источник
11
Как просто «переключиться на Kotlin»? Это вопрос Java.
ehecatl
2
Преобразование Java LocalDate в Date является распространенной, раздражающей проблемой для любого разработчика JVM. Это решение для разработчиков Kotlin.
gyoder
-1
public static Date convertToTimeZone(Date date, String tzFrom, String tzTo) {
    return Date.from(LocalDateTime.ofInstant(date.toInstant(), ZoneId.of(tzTo)).atZone(ZoneId.of(tzFrom)).toInstant());
} 
Уильям Нгуен
источник
2
Пожалуйста, объясните ваше решение.
Мартин Забель
-2

просто

public Date convertFrom(LocalDate date) {
    return java.sql.Timestamp.valueOf(date.atStartOfDay());
}
Артур Луис Оливейра
источник
-3
java.util.Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
Махендра Шри
источник
Чем ваш ответ отличается от принятого через 4 года? Копировать-вставить для достижения повышения репутации?
жало