Ich habe mit der neuen Datums- / Uhrzeit-API gespielt, aber als ich diese ausführte:
public class Test {
public static void main(String[] args){
String dateFormatted = LocalDate.now()
.format(DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(dateFormatted);
}
}
Es wirft:
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
at java.time.LocalDate.get0(LocalDate.java:680)
at java.time.LocalDate.getLong(LocalDate.java:659)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
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.LocalDate.format(LocalDate.java:1685)
at Test.main(Test.java:23)
Wenn ich mir den Quellcode der LocalDate-Klasse ansehe, sehe ich:
private int get0(TemporalField field) {
switch ((ChronoField) field) {
case DAY_OF_WEEK: return getDayOfWeek().getValue();
case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
case DAY_OF_MONTH: return day;
case DAY_OF_YEAR: return getDayOfYear();
case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
case MONTH_OF_YEAR: return month;
case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
case YEAR: return year;
case ERA: return (year >= 1 ? 1 : 0);
}
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
}
Wie im Dokument beschrieben:
Diese Methode erstellt einen Formatierer basierend auf einem einfachen Muster aus Buchstaben und Symbolen, wie in der Klassendokumentation beschrieben.
Und all diese Buchstaben sind definiert .
Warum dürfen DateTimeFormatter.ofPattern
wir also keine Musterbuchstaben verwenden?
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfWeek
DateTimeFormatter.ofPattern("HH:mm:ss")
Ich möchte der richtigen Antwort von @James_D folgende Details hinzufügen:
Hintergrund: Die meisten Datums- und
java.util.Calendar
Zeitbibliotheken ( in Java siehe auch .Net-DateTime oderDate
in JavaScript oderDateTime
in Perl) basieren auf dem Konzept eines universellen, universellen, einzigartigen Zeittyps (auf Deutsch gibt es den poetischen Ausdruck " eierlegende Wollmilchsau "). In diesem Design darf es kein nicht unterstütztes Feld geben. Aber der Preis ist hoch: Viele Zeitprobleme können mit einem solch unflexiblen Ansatz nicht angemessen behandelt werden, da es schwierig bis unmöglich ist, einen gemeinsamen Nenner für alle Arten von zeitlichen Objekten zu finden.JSR-310 hat einen anderen Weg gewählt , nämlich verschiedene zeitliche Typen zuzulassen, die aus typspezifischen Sätzen unterstützter integrierter Felder bestehen. Die natürliche Folge ist, dass nicht jedes mögliche Feld von jedem Typ unterstützt wird (und Benutzer sogar ihre eigenen Spezialfelder definieren können). Es ist auch möglich , jedes Objekt des Typs programmgesteuert
TemporalAccessor
nach seinem spezifischen Satz unterstützter Felder zu fragen . DennLocalDate
wir finden:Es gibt kein HOUR_OF_DAY-Feld, das das Problem von erklärt
UnsupportedTemporalTypeException
. Und wenn wir uns die JSR-310- Zuordnung von Mustersymbolen zu Feldern ansehen, sehen wir, dass das Symbol H nicht unterstütztem HOUR_OF_DAY zugeordnet ist:Diese Feldzuordnung bedeutet nicht, dass das Feld vom konkreten Typ unterstützt wird. Das Parsen erfolgt in mehreren Schritten. Die Feldzuordnung ist nur der erste Schritt. Der zweite Schritt ist dann das Parsen auf ein Rohobjekt vom Typ
TemporalAccessor
. Und schließlich analysieren Sie die Delegaten auf den Zieltyp (hier :)LocalDate
und lassen Sie ihn entscheiden, ob alle Feldwerte im analysierten Zwischenobjekt akzeptiert werden.quelle
Die richtige Klasse für mich war
ZonedDateTime
sowohl die Zeit als auch die Zeitzone.LocalDate
hat nicht die Zeitinformationen, so dass Sie eine erhaltenUnsupportedTemporalTypeException: Unsupported field: HourOfDay
.Sie können verwenden,
LocalDateTime
aber dann haben Sie nicht die Zeitzoneninformationen. Wenn Sie also versuchen, darauf zuzugreifen (selbst wenn Sie einen der vordefinierten Formatierer verwenden), erhalten Sie eineUnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
.quelle