У меня есть Instant из источника, который, согласно спецификации, должен быть LocalDate, но не вижу никаких методов в LocalDate для преобразования. Как лучше всего это сделать?
Как преобразовать Instant в LocalDate
Ответы (6)
Ява 9+
LocalDate.ofInstant(...);
появился в Java 9.
Instant instant = Instant.parse( "2020-01-23T00:00:00Z" );
ZoneId z = ZoneId.of( "America/Edmonton" );
LocalDate ld = LocalDate.ofInstant( instant , z );
См. запуск кода в реальном времени на IdeOne.com.
Обратите внимание, что дата – 22-е, а не 23-е, поскольку в этом часовом поясе используется смещение на несколько часов раньше UTC.
2020-01-22
Ява 8
ZonedDateTime
имеет метод .toLocalDate()
в Java 8.
yourInstant.atZone(yourZoneId).toLocalDate();
Будет работать с более ранними версиями LocalDate...
ZoneOffset.UTC
например
- person Pipo; 01.05.2021
Другие ответы предоставили механику преобразования, но я хотел добавить некоторую информацию о значении такого преобразования, которое, надеюсь, поможет объяснить, почему оно работает так, как работает.
LocalDate
и Instant
кажутся похожими — они оба содержат информацию о дате (/ времени) без информации о часовом поясе. Однако они имеют совсем другое значение.
Instant
однозначно представляет момент времени. Представление явно не содержит какой-либо часовой пояс, но неявно относится к временной шкале UTC.
LocalDateTime
(и LocalDate
) неоднозначны, потому что они представляют точку на местной временной шкале, которая неявно указывает на местный часовой пояс.
Итак, чтобы правильно преобразовать Instant
в LocalDateTime
(концептуально — некоторые из этих шагов объединены в одну операцию в реализации), вам необходимо:
1. преобразовать Instant
в ZonedDateTime
, применив время UTC. информация о зоне
2. изменить часовой пояс с UTC на местный часовой пояс (что подразумевает применение соответствующего смещения часового пояса), что дает вам еще ZonedDateTime
(с другим часовым поясом)
3 . преобразовать ZonedDateTime
в LocalDateTime
, что сделает часовой пояс неявным (местным), удалив информацию о часовом поясе.
Наконец, вы можете отбросить временную часть LocalDateTime
и получить LocalDate
.
Если вы используете java 8, вы можете сделать следующее
Instant instantOfNow = Instant.now();
LocalDate localDate
= LocalDateTime.ofInstant(instantOfNow, ZoneOffset.UTC).toLocalDate();
Вам нужно спросить себя, в какое смещение зоны вы хотите преобразовать его, наиболее вероятно, и когда вы знаете ответ на этот вопрос:
LocalDate.ofInstant(yourInstant, yourZoneOffSet)
ИЗМЕНИТЬ
только что понял, что это возможно только с java-9, для pre-java9 см. другой ответ
Instant instant = Instant.now();
LocalDate localDate = LocalDate.ofInstant(instant, ZoneOffset.UTC);
приведенный выше код работал для меня.
Полный рабочий пример, совместимый с Java 8:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
class Scratch {
public static void main(String[] args) {
Instant now = Instant.now();
LocalDateTime ldt = now.atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(ldt);
}
}