Как конвертировать ZonedDateTime в Date?
Я пытаюсь установить серверное агностическое время даты в моей базе данных, и я считаю, что лучшая практика для этого-установить дату и время UTC. Мой сервер БД-это Cassandra, и драйвер БД для Java понимает только тип даты.
Итак, предполагая, что в моем коде я использую новый Java 8 ZonedDateTime, чтобы получить UTC сейчас (ZonedDateTime.now(ZoneOffset.UTC)), Как я могу преобразовать этот экземпляр ZonedDateTime в класс даты "legacy"?
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);
Я использую это.
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