Відформатуйте LocalDateTime за допомогою часового поясу на Java8


121

У мене є такий простий код:

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
LocalDateTime.now().format(FORMATTER)

Тоді я отримаю наступне виняток:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
at java.time.LocalDate.get0(LocalDate.java:680)
at java.time.LocalDate.getLong(LocalDate.java:659)
at java.time.LocalDateTime.getLong(LocalDateTime.java:720)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$OffsetIdPrinterParser.format(DateTimeFormatterBuilder.java:3315)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1745)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1719)
at java.time.LocalDateTime.format(LocalDateTime.java:1746)

Як вирішити це питання?

Відповіді:


212

LocalDateTime- дата-час без часового поясу. Ви вказали символ формату зміщення часового поясу у форматі, однак LocalDateTimeтакої інформації немає. Тому сталася помилка.

Якщо ви хочете інформацію про часовий пояс, вам слід скористатися ZonedDateTime.

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
ZonedDateTime.now().format(FORMATTER);
=> "20140829 14:12:22.122000 +09"

3
Супер корисно. Не впевнений, я би так легко зловив шматок часового поясу. Чудова відповідь. Дякую!
Ларан Еванс,

40

Префікс "Місцевий" в JSR-310 (він же java.time-package в Java-8) не вказує на наявність інформації про часовий пояс у внутрішньому стані цього класу (тут:) LocalDateTime. Незважаючи на часто оманливу назву, такі класи люблять LocalDateTimeабо не LocalTimeмістять інформації про часовий пояс або компенсують .

Ви спробували відформатувати такий часовий тип (який не містить зміщення) з інформацією про зсув (позначений символом візерунка Z). Тож форматник намагається отримати доступ до недоступної інформації і повинен кинути виняток, який ви спостерігали.

Рішення:

Використовуйте тип, який має таку інформацію про зміщення або часовий пояс. У JSR-310 це або OffsetDateTime(що містить зміщення, але не часовий пояс, включаючи правила DST), або ZonedDateTime. Ви можете переглянути всі підтримувані поля такого типу, відвідавши метод isSupported (TemporalField). . Поле OffsetSecondsпідтримується в OffsetDateTimeі ZonedDateTime, але не в LocalDateTime.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
String s = ZonedDateTime.now().format(formatter);

З яким префіксом ви замінили б префікс "Місцевий", щоб уникнути плутанини?
Метью

@Matthew Була також дискусія, ініційована Bank Credit Suisse, пропонуючи назву PlainDateTimeі т.д. Якби ми були ще до Java v1.0, то жоден префікс не був би кращим, але назви, подібні Dateтощо, вже зарезервовані старим JDK.
Meno Hochschild

-4

LocalDateTime.now (). Формат (DateTimeFormatter.ofPattern ("yyyyMMdd HH: mm: ss.SSSSSS Z"));

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.