LocalDate для java.util.Date и наоборот самое простое преобразование?
Есть ли простой способ конвертировать LocalDate
(введено в Java 8) для java.util.Date
объект?
Под "простым" я подразумеваю более простой, чем этот:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
что мне немного неловко
Поскольку нас интересует только часть даты, а информация о часовом поясе отсутствует ни в одном из объектов, зачем вводить временные пояса в явном виде? Время полуночи и часовой пояс системы по умолчанию должны приниматься неявно для преобразования.
7 ответов
На самом деле есть. Есть статический метод valueOf в java.sql.Date
объект, который делает именно это. Итак, мы имеем
java.util.Date date = java.sql.Date.valueOf(localDate);
и это все. Нет явной установки часовых поясов, потому что местный часовой пояс взят неявно.
Из документов:
Предоставленная LocalDate интерпретируется как местная дата в местном часовом поясе.
java.sql.Date
подклассы java.util.Date
так что результат java.util.Date
также.
И для обратной операции есть метод toLocalDate в классе java.sql.Date. Итак, мы имеем:
LocalDate ld = new java.sql.Date(date.getTime()).toLocalDate();
ТЛ; др
Есть ли простой способ преобразовать 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.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 );
Больше информации
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как java.util.Date
, Calendar
& SimpleDateFormat
,
Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.
Чтобы узнать больше, смотрите Oracle Tutorial. И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
классы.
Где взять классы java.time?
- Java SE 8, Java SE 9 и более поздние
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
- Android
- Более поздние версии Android связывают реализации классов java.time.
- Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP….
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие как Interval
, YearWeek
, YearQuarter
и многое другое.
Дата -> LocalDate:
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate -> Date:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
Преобразование 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);
Дата в 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());
Я решил этот вопрос с решением ниже
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 выведите вашу дату в следующем формате: "гггг-мм-дд"
Вы можете конвертировать java.util.Date
возражать в String
объект, который будет форматировать дату как гггг-мм-дд.
LocalDate имеет parse
метод, который преобразует его в LocalDate
объект. Строка должна представлять действительную дату и анализируется с использованием DateTimeFormatter.ISO_LOCAL_DATE.
Дата в LocalDate
LocalDate.parse(Date.toString())