Как преобразовать java.util.Date в java.time.LocalDate и сохранить дату/время

Я пытаюсь преобразовать java.util.Date в java.time.LocalDate:

[java.util.Date instance].toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

Однако есть случай, когда [java.util.Date instance] имеет дневное время, например: 22:25, и я выбираю ZoneId, например, так: ZoneId.of("Asia/Singapore").

У исходящего LocalDate будет другой день (потому что эта зона добавляет +6 часов), как, например, Европа/Минск:

printing java.util.Date: Thu Mar 04 22:25:00 CET 2021
printing converted java.util.Date to java.time.LocalDate with Europe/Minsk: 2021-03-04
printing converted java.util.Date to java.time.LocalDate with Asia/Singapore: 2021-03-05

и я хочу сохранить ту же дату в результирующих LocalDate, что и в этом экземпляре Date. Некоторые подходы, как решить эту проблему? Я предполагаю, что может быть несколько способов.


person Wortig    schedule 05.03.2021    source источник


Ответы (4)


Вы можете просто преобразовать его в мгновенный, установить часовой пояс в UTC, потому что java.util.Date использует UTC.

public static LocalDate convert (Date date) {
    return date.toInstant()
      .atZone(ZoneId.of("UTC"))
      .toLocalDate();
}
person carlosvin    schedule 05.03.2021

Instant всегда дает вам дату и время в UTC, и если вы хотите сохранить ту же дату, вам нужно использовать смещение зоны UTC.

Демонстрация:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        String strDateTime = "10/02/2021 22:25";
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm", Locale.ENGLISH);
        Date date = sdf.parse(strDateTime);
        Instant instant = date.toInstant();
        ZonedDateTime zdt = instant.atZone(ZoneOffset.UTC);
        LocalDate localDate = zdt.toLocalDate();
        System.out.println(localDate);
    }
}

Вывод:

2021-10-02

Узнайте больше о современном API даты и времени из Trail: Date Time< /а>.


java.util API даты и времени и их API форматирования SimpleDateFormat устарели и подвержены ошибкам. Рекомендуется полностью прекратить их использование и перейти на современный API даты и времени. По какой-либо причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который переносит большую часть функций java.time на Java 6 и 7. Если вы работаете над проектом Android и вашим уровнем Android API по-прежнему не совместим с Java-8, проверьте Java 8+ API, доступные через дешугаринг и Как использовать ThreeTenABP в проекте Android.

person Arvind Kumar Avinash    schedule 05.03.2021
comment
Ты был быстрее. Верно, ZoneId.systemDefault() зависит от местоположения, поэтому ZoneOffset.UTC — хороший выбор, чтобы понять LocalDate независимо от того, где мы находимся. - person Nikolas Charalambidis; 05.03.2021

Вы можете просто скопировать значения Date в LocalDate без преобразования данных:

LocalDate.of(date.getYear(), date.getMonth()+1, date.getDate());
person Benjamin M    schedule 05.03.2021
comment
Методы даты getXxx устарели в течение 24 лет. По уважительной причине: они работают ненадежно в разных часовых поясах. Не делай этого так. - person Ole V.V.; 07.03.2021

Извините, вы просите невозможного. Несмотря на свое название, устаревший класс Date не представляет дату. Он представляет момент времени. На тот момент вполне могли быть две разные даты в Сингапуре и Минске. Невозможно сохранить ту же дату, поскольку у вас не было даты с самого начала.

person Ole V.V.    schedule 07.03.2021
comment
Если вы считаете, что мой вопрос задан неправильно, предложите редактирование. - person Wortig; 07.03.2021
comment
Я думаю, что вопрос хорош в его нынешнем виде. Распространенная ошибка думать, что вы можете получить однозначную дату из Date. Так что ваш вопрос и мой ответ могут помочь будущим читателям прояснить, что это не так. - person Ole V.V.; 07.03.2021