LocalDate - java.util.Date и наоборот - простое преобразование?
Есть ли простой способ преобразовать LocalDate
(представленный в Java 8) в объект java.util.Date
?
Под "простым" я подразумеваю более простой, чем этот:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
что мне немного неловко
Поскольку нас интересует только часть даты, а информация о часовом поясе отсутствует ни в одном из объектов, зачем вводить часовые пояса в явном виде? Полуночное время и часовой пояс системы по умолчанию должны приниматься неявно для преобразования.
Ответы
Ответ 1
На самом деле есть. В объекте java.sql.Date
есть статический метод valueOf, который делает именно это. Итак, у нас есть
java.util.Date date = java.sql.Date.valueOf(localDate);
и что это. Нет явной настройки часовых поясов, потому что локальный часовой пояс взят неявно.
Из документов:
Предоставленная LocalDate интерпретируется как локальная дата в локальном часовой пояс.
Подклассы java.sql.Date
java.util.Date
, поэтому результатом является также java.util.Date
.
А для обратной операции в классе java.sql.Date есть метод toLocalDate. Итак, мы имеем:
LocalDate ld = new java.sql.Date(date.getTime()).toLocalDate();
Ответ 2
ТЛ; др
Есть ли простой способ преобразовать LocalDate (представленный в Java 8) в объект java.util.Date? Под "простым" я имею в виду более простой, чем этот
Нет. Вы сделали это правильно и максимально кратко.
java.util.Date.from( // Convert from modern java.time class to troublesome old legacy class. DO NOT DO THIS unless you must, to inter operate with old code not yet updated for java.time.
myLocalDate // 'LocalDate' class represents a date-only, without time-of-day and without time zone nor offset-from-UTC.
.atStartOfDay( // Let java.time determine the first moment of the day on that date in that zone. Never assume the day starts at 00:00:00.
ZoneId.of( "America/Montreal" ) // Specify time zone using proper name in 'continent/region' format, never 3-4 letter pseudo-zones such as 'PST', 'CST', 'IST'.
) // Produce a 'ZonedDateTime' object.
.toInstant() // Extract an 'Instant' object, a moment always in UTC.
)
Прочтите ниже вопросы, а затем подумайте об этом. Как это может быть проще? Если вы спросите меня, в какое время начинается свидание, как еще я могу ответить, но спросить вас "Где?"? Новый день наступает раньше в парижском ФР, чем в Монреале, Калифорния, и еще раньше в Калькутте, и даже раньше, в Окленде, Новая Зеландия, все в разные моменты.
Таким образом, при преобразовании только даты (LocalDate
) в дату и время мы должны применить часовой пояс (ZoneId
), чтобы получить зонированное значение (ZonedDateTime
), а затем перейти в UTC (Instant
) для соответствует определению java.util.Date
.
Подробнее
Во-первых, по возможности избегайте старых устаревших классов даты и времени, таких как java.util.Date
. Они плохо разработаны, сбивают с толку и хлопотно. Они были вытеснены классами java.time по причине, фактически по многим причинам.
Но если вам нужно, вы можете конвертировать в/из типов java.time в старые. Ищите новые методы преобразования, добавленные к старым классам.
java.util.Date
→ java.time.LocalDate
Имейте в виду, что java.util.Date
является неверным, поскольку представляет дату плюс время в UTC. Напротив, LocalDate
класс представляет значение только для даты без времени суток и без часового пояса.
Переход от java.util.Date
к java.time означает преобразование в эквивалентный класс java.time.Instant
. Класс Instant
представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).
Instant instant = myUtilDate.toInstant();
Класс LocalDate
представляет значение только для даты без времени суток и без часового пояса.
Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париже Франция - это новый день, который все еще "вчера" в Монреале-Квебеке.
Поэтому нам нужно переместить этот Instant
во временную зону. Мы применяем ZoneId
, чтобы получить ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Оттуда попросите только дату, LocalDate
.
LocalDate ld = zdt.toLocalDate();
java.time.LocalDate
→ java.util.Date
Чтобы перейти в другом направлении, от java.time.LocalDate
к java.util.Date
означает, что мы переходим от даты только к дате и времени. Поэтому мы должны указать время суток. Вы, вероятно, хотите пойти в первый момент дня. Не думайте, что это 00:00:00
. Аномалии, такие как переход на летнее время (DST), означают, что первый момент может быть другим временем, таким как 01:00:00
. Пусть java.time определит это значение, вызвав atStartOfDay
на LocalDate
.
ZonedDateTime zdt = myLocalDate.atStartOfDay( z );
Теперь извлеките Instant
.
Instant instant = zdt.toInstant();
Преобразуйте это Instant
в java.util.Date
, позвонив from( Instant )
.
java.util.Date d = java.util.Date.from( instant );
Подробнее
![Table of date-time types in Java, both legacy and modern.]()
О java.time
Среда java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Проект Joda-Time, который теперь находится в режиме обслуживания, рекомендует выполнить переход на классы java.time.
Чтобы узнать больше, см. Учебное пособие по Oracle. И поищите в Кару множество примеров и объяснений. Спецификация: JSR 310.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версией. Нет необходимости в строках, нет необходимости в классах java.sql.*
.
Где взять классы java.time?
![Table of which java.time library to use with which version of Java or Android]()
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и еще.
Ответ 3
Дата → LocalDate:
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate → Дата:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
Ответ 4
Дата в LocalDate
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate to Date
LocalDate localDate = LocalDate.now();
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
Ответ 5
Преобразование LocalDateTime в java.util.Date
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.systemDefault());
Instant instant = zonedDateTime.toInstant();
Date date = Date.from(instant);
System.out.println("Result Date is : "+date);
Ответ 6
java.time.LocalDate to java.util.Date
Date date = Date.from(Instant.from(LocalDate.now()));
java.util.Date для java.time.LocalDate
LocalDate.from(new Date().toInstant())
Ответ 7
Я решил этот вопрос с решением ниже
import org.joda.time.LocalDate;
Date myDate = new Date();
LocalDate localDate = LocalDate.fromDateFields(myDate);
System.out.println("My date using Date" Nov 18 11:23:33 BRST 2016);
System.out.println("My date using joda.time LocalTime" 2016-11-18);
В этом случае localDate напечатает вашу дату в этом формате "yyyy-MM-dd"
Ответ 8
Вы можете преобразовать объект java.util.Date
в объект String
, который будет форматировать дату как yyyy-mm-dd.
LocalDate имеет метод parse
, который преобразует его в объект LocalDate
. Строка должна представлять действительную дату и анализируется с использованием DateTimeFormatter.ISO_LOCAL_DATE.
Дата в LocalDate
LocalDate.parse(Date.toString())