Как конвертировать ZonedDateTime в Date?



Я пытаюсь установить серверное агностическое время даты в моей базе данных, и я считаю, что лучшая практика для этого-установить дату и время UTC. Мой сервер БД-это Cassandra, и драйвер БД для Java понимает только тип даты.



Итак, предполагая, что в моем коде я использую новый Java 8 ZonedDateTime, чтобы получить UTC сейчас (ZonedDateTime.now(ZoneOffset.UTC)), Как я могу преобразовать этот экземпляр ZonedDateTime в класс даты "legacy"?

676   8  

8 ответов:

вы можете конвертировать ZonedDateTime в мгновение, которое вы можете использовать непосредственно с датой.

Date.from(java.time.ZonedDateTime.now().toInstant());

tl; dr

java.util.Date.from(  // Transfer the moment in UTC, truncating any microseconds or nanoseconds to milliseconds.
    Instant.now() ;   // Capture current moment in UTC, with resolution as fine as nanoseconds.
)

хотя не было никакого смысла в этом коде выше. Оба java.util.Date и Instant представляют момент в UTC, всегда в UTC. Код выше имеет тот же эффект, что и:

new java.util.Date()  // Capture current moment in UTC.

здесь нет пользы от использования ZonedDateTime. Если у вас уже есть ZonedDateTime, подстраиваться мирового путем экстракции Instant.

java.util.Date.from(             // Truncates any micros/nanos.
    myZonedDateTime.toInstant()  // Adjust to UTC. Same moment, same point on the timeline, different wall-clock time.
)

Другой Ответ Правильный

The ответ by ssoltanid правильно обращается к вашей конкретной вопрос, Как конвертировать новую школу java.объект времени (ZonedDateTime) в старую школу java.util.Date, теперь режим обслуживания, советует миграция в java.время классы.

чтобы узнать больше, смотрите Oracle Tutorial. И поиск переполнения стека для многих примеры и пояснения. Спецификация является JSR 310.

вы можете обменять java.время объекты непосредственно с вашей базой данных. Используйте - драйвера соответствуют JDBC 4.2 или позже. Нет необходимости в строках, нет необходимости в java.sql.* классы.

где получить java.время занятий?

  • Java SE 8, Java SE 9, Java SE 10, и позже
    • встроенный.
    • часть стандартного Java API с комплектной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • большая часть java.функциональность время портированы с Java 6 и 7 в ThreeTen-Backport.
  • Android
    • более поздние версии Android bundle реализации java.время классы.
    • для более ранних Android ( ThreeTenABP проект приспосабливается ThreeTen-Backport (упомянутый выше.) Смотрите как использовать ThreeTenABP....

The ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательным полигоном для возможных будущих дополнений к java.время. Вы можете найти некоторые полезные классы, такие как Interval,YearWeek,YearQuarter и больше.

вот пример преобразования текущего системного времени в UTC. Он включает в себя форматирование ZonedDateTime в виде строки, а затем объект String будет проанализирован в объект date с помощью java.текст DateFormat.

    ZonedDateTime zdt = ZonedDateTime.now(ZoneOffset.UTC);
    final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
    final DateFormat FORMATTER_YYYYMMDD_HH_MM_SS = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
    String dateStr = zdt.format(DATETIME_FORMATTER);

    Date utcDate = null;
    try {
        utcDate = FORMATTER_YYYYMMDD_HH_MM_SS.parse(dateStr);
    }catch (ParseException ex){
        ex.printStackTrace();
    }

Если вы используете портировать ThreeTen для Android и не может использовать новые Date.from(Instant instant) (что требует минимум API 26) Вы можете использовать:

ZonedDateTime zdt = ZonedDateTime.now();
Date date = new Date(zdt.toInstant().toEpochMilli());

или:

Date date = DateTimeUtils.toDate(zdt.toInstant());

пожалуйста, Также прочитайте советы в ответ Василия Бурка

вы можете сделать это с помощью java.время классы, встроенные в Java 8 и выше.

ZonedDateTime temporal = ...
long epochSecond = temporal.getLong(INSTANT_SECONDS);
int nanoOfSecond = temporal.get(NANO_OF_SECOND);
Date date = new Date(epochSecond * 1000 + nanoOfSecond / 1000000);

Если вас интересует только сейчас, то просто используйте:

Date d = new Date();

Я использую это.

public class TimeTools {

    public static Date getTaipeiNowDate() {
        Instant now = Instant.now();
        ZoneId zoneId = ZoneId.of("Asia/Taipei");
        ZonedDateTime dateAndTimeInTai = ZonedDateTime.ofInstant(now, zoneId);
        try {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateAndTimeInTai.toString().substring(0, 19).replace("T", " "));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

потому что Date.from(java.time.ZonedDateTime.ofInstant(now, zoneId).toInstant()); Это не работа!!! Если вы запустите приложение на своем компьютере, это не проблема. Но если вы работаете в любом регионе AWS или Docker или GCP, это создаст проблему. Потому что компьютер не ваш часовой пояс на облаке. Вы должны правильно установить часовой пояс в коде. Например, Азия / Тайбэй. Затем он будет исправлен в AWS или Docker или GCP.

public class App {
    public static void main(String[] args) {
        Instant now = Instant.now();
        ZoneId zoneId = ZoneId.of("Australia/Sydney");
        ZonedDateTime dateAndTimeInLA = ZonedDateTime.ofInstant(now, zoneId);
        try {
            Date ans = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateAndTimeInLA.toString().substring(0, 19).replace("T", " "));
            System.out.println("ans="+ans);
        } catch (ParseException e) {
        }
        Date wrongAns = Date.from(java.time.ZonedDateTime.ofInstant(now, zoneId).toInstant());
        System.out.println("wrongAns="+wrongAns);
    }
}

для приложения docker, такого как beehuang commented, вы должны установить свой часовой пояс.

в качестве альтернативы вы можете использовать withZoneSameLocal. Например:

2014-07-01T00:00+02:00[GMT+02:00] преобразуется в

Date.from(zonedDateTime.withZoneSameLocal(ZoneId.systemDefault()).toInstant())

до Вт Jul 01 00: 00: 00 CEST 2014 и

Date.from(zonedDateTime.toInstant())

до Пн 30 июня 22: 00: 00 UTC 2014

Comments

    Ничего не найдено.