Java8'de Saat Dilimi ile LocalDateTime'ı biçimlendirme


121

Şu basit koda sahibim:

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

O zaman şu istisnayı alacağım:

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)

Bu sorun nasıl çözülür?

Yanıtlar:


212

LocalDateTimesaat dilimi olmayan bir tarih-saattir. Biçimde saat dilimi uzaklık biçimi simgesini belirttiniz, ancak LocalDateTimeböyle bir bilgiye sahip değilsiniz. Bu yüzden hata oluştu.

Saat dilimi bilgisi istiyorsanız, kullanmalısınız ZonedDateTime.

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

3
Çok yardımcı oldu. Zaman dilimi parçasını bu kadar kolay yakalayabilirdim emin değilim. Mükemmel cevap. Teşekkür ederim!
Laran Evans

40

JSR-310'daki "Yerel" öneki (Java-8'de java.time-paketi olarak da bilinir), bu sınıfın dahili durumunda bir saat dilimi bilgisi olduğunu göstermez (burada:) LocalDateTime. Gibi sık sık yanıltıcı adı böyle sınıflara rağmen LocalDateTimeveya LocalTimeHAYIR saat dilimi bilgileri veya ofset var .

Böyle bir zamansal türü (herhangi bir ofset içermeyen) ofset bilgisiyle (desen sembolü Z ile gösterilir) biçimlendirmeyi denediniz. Bu nedenle, formatlayıcı, mevcut olmayan bir bilgiye erişmeye çalışır ve gözlemlediğiniz istisnayı atması gerekir.

Çözüm:

Böyle bir fark veya saat dilimi bilgisine sahip bir tür kullanın. JSR-310'da bu, ya OffsetDateTime(bir uzaklık içerir, ancak DST kurallarını içeren bir saat dilimi içermez) veya ZonedDateTime. İsSupported (TemporalField) yöntemine bakarak bu türden desteklenen tüm alanları izleyebilirsiniz . . Alan ve OffsetSecondsiçinde desteklenir , ancak içinde desteklenmez .OffsetDateTimeZonedDateTimeLocalDateTime

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

Karışıklığı önlemek için "Yerel" ön ekini hangi ön ekle değiştirirdiniz?
Matthew

@Matthew Ayrıca, Bank Credit Suisse tarafından başlatılan ve adı vb. Öneren bir tartışma vardıPlainDateTime . Muhtemelen daha iyi çünkü "sade" öneki tarih-saatten başka bir şey olmadığını gösteriyor. Hala Java v1.0'dan önce olsaydık, hiçbir önek daha iyi olmazdı, ancak Datevs. gibi isimler zaten eski JDK tarafından ayrılmıştır.
Meno Hochschild

-4

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.