конвертировать дату в LocalDate или LocalDateTime и обратно

Конвертировать дату в LocalDate или LocalDateTime и обратно

1. обзор

Начиная с Java 8, у нас появился новый Date API -java.time.

Однако иногда нам все еще нужно выполнять преобразования между новым и старым API и работать с представлениями дат из обоих.

Дальнейшее чтение:

Миграция на новый Java 8 Date Time API

Краткое практическое руководство по переходу на новый API DateTime в Java 8.

Read more

Введение в API даты / времени Java 8

В этой статье мы рассмотрим новые API-интерфейсы Java 8 для даты и времени и насколько проще будет создавать даты и время и манипулировать ими.

Read more

2. Преобразованиеjava.util.Date вjava.time.LocalDate

Начнем с преобразования старого представления даты в новое.

Здесь мы можем воспользоваться новымtoInstant() method which was added to java.util.Date в Java 8.

Когда мы конвертируемInstantobject, it’s required to use a ZoneId, because _ _Instant objects are timezone-agnostic - просто точки на временной шкале.

APIatZone(ZoneId zone) из объектаInstant возвращаетZonedDateTime, поэтому нам просто нужно извлечь из негоLocalDate с помощью методаtoLocalDate().

В нашем первом примере мы используем систему по умолчаниюZoneId:

public LocalDate convertToLocalDateViaInstant(Date dateToConvert) {
    return dateToConvert.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
}

A similar solution to the above one, but with a different way of creating an Instant object - методомofEpochMilli():

public LocalDate convertToLocalDateViaMilisecond(Date dateToConvert) {
    return Instant.ofEpochMilli(dateToConvert.getTime())
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
}

Прежде чем мы продолжим, давайте также кратко рассмотрим классold java.sql.Date и то, как его также можно преобразовать вLocalDate.

Начиная с Java 8, мы можем найти дополнительный методtoLocalDate() дляjava.sql.Date, который также дает нам простой способ преобразовать его вjava.time.LocalDate.

В этом случае нам не нужно беспокоиться о часовом поясе:

public LocalDate convertToLocalDateViaSqlDate(Date dateToConvert) {
    return new java.sql.Date(dateToConvert.getTime()).toLocalDate();
}

Точно так же мы можем преобразовать старый объектDate в объектLocalDateTime - давайте посмотрим на это дальше.

3. Преобразованиеjava.util.Date вjava.time.LocalDateTime

Чтобы получить экземплярLocalDateTime, мы можем аналогичным образом использоватьan intermediary ZonedDateTime, and then using the toLocalDateTime() API.

Как и раньше, мы можем использовать два возможных решения для получения объектаInstant изjava.util.Date:

public LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert) {
    return dateToConvert.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDateTime();
}

public LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert) {
    return Instant.ofEpochMilli(dateToConvert.getTime())
      .atZone(ZoneId.systemDefault())
      .toLocalDateTime();
}

И, начиная с Java 8, мы также можемuse java.sql.Timestamp to obtain a LocalDateTime:

ocalDateTime convertToLocalDateTimeViaSqlTimestamp(Date dateToConvert) {
    return new java.sql.Timestamp(
      dateToConvert.getTime()).toLocalDateTime();
}

4. Преобразоватьjava.time.LocalDate вjava.util.Date

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

Мы обсудим два возможных способа преобразованияLocalDate вDate.

В первом мы используем новый объектvalueOf(LocalDate date) method provided injava.sql.Date, который принимаетLocalDate в качестве параметра:

public Date convertToDateViaSqlDate(LocalDate dateToConvert) {
    return java.sql.Date.valueOf(dateToConvert);
}

Как мы видим, это легко и интуитивно понятно. Он использует местный часовой пояс для конвертации (все сделано под капотом, не нужно беспокоиться).

В другом примере, Java 8, мы используем объектInstant, который мы передаем объектуfrom(Instant instant)method ofjava.util.Date:

public Date convertToDateViaInstant(LocalDate dateToConvert) {
    return java.util.Date.from(dateToConvert.atStartOfDay()
      .atZone(ZoneId.systemDefault())
      .toInstant());
}

Вы заметите, что мы используем здесь объектInstant, и нам также нужно учитывать часовые пояса при выполнении этого преобразования.

Затем давайте воспользуемся очень похожими решениями для преобразованияLocalDateTime в объектDate.

5. Преобразоватьjava.time.LocalDateTime вjava.util.Date

Самый простой способ получитьa java.util.Date from LocalDateTime is to use an extension to thejava.sql.Timestamp - доступен в Java 8:

public Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) {
    return java.sql.Timestamp.valueOf(dateToConvert);
}

Но, конечно, альтернативное решение используетan Instant object – which we obtain from ZonedDateTime:

Date convertToDateViaInstant(LocalDateTime dateToConvert) {
    return java.util.Date
      .from(dateToConvert.atZone(ZoneId.systemDefault())
      .toInstant());
}

6. Дополнения Java 9

В Java 9 доступны новые методы, упрощающие преобразование междуjava.util.Date иjava.time.LocalDate илиjava.time.LocalDateTime.

LocalDate.ofInstant(Instant instant, ZoneId zone) иLocalDateTime.ofInstant(Instant instant, ZoneId zone) предоставляют удобные ярлыки:

public LocalDate convertToLocalDate(Date dateToConvert) {
    return LocalDate.ofInstant(
      dateToConvert.toInstant(), ZoneId.systemDefault());
}

public LocalDateTime convertToLocalDateTime(Date dateToConvert) {
    return LocalDateTime.ofInstant(
      dateToConvert.toInstant(), ZoneId.systemDefault());
}

7. Заключение

В этом руководстве мы рассмотрели возможные способы преобразования старогоjava.util.Date в новыеjava.time.LocalDate иjava.time.LocalDateTime и другие способы.

Полная реализация этой статьи доступнаover on Github.