Wie konvertiert man java.util.Date in Java8 java.time.YearMonth

9

Wie kann ich am besten ein java.util.Date in ein Java 8 java.time.YearMonth konvertieren?

Leider wirft das folgende ein DateTimeException :

%Vor%

ergibt:

%Vor%

Ich brauche diese Funktionalität, da ich YearMonth -Werte in einer Datenbank mit JPA speichern möchte. Momentan unterstützt JPA YearMonth nicht, daher habe ich den folgenden YearMonthConverter entwickelt (Import ausgelassen):

%Vor%

Gibt es keine bessere (sauberere, kürzere) Lösung (für beide Richtungen)?

    
Sebastian 08.01.2015, 15:04
quelle

1 Antwort

13

Kurze Antwort:

%Vor%

Erläuterung:

Der JavaDoc von JahrMonat.von (TemporalAccessor) -Methode sagt:

  

Die Konvertierung extrahiert die Felder YEAR und MONTH_OF_YEAR. Die Extraktion ist nur erlaubt, wenn das temporäre Objekt eine ISO-Chronologie hat oder in ein LocalDate konvertiert werden kann.

Sie müssen also entweder:

  1. Extrahieren Sie die Felder YEAR und MONTH_OF_YEAR oder
  2. Sie sollten etwas verwenden, das in ein LocalDate konvertiert werden kann.

Lass es uns versuchen!

%Vor%

Dies ist nicht möglich, eine Ausnahme wird ausgelöst:

  

java.time.temporal.UnsupportedTemporalTypeException: Nicht unterstütztes Feld: Jahr       bei java.time.Instant.get (Instant.java:571)       ...

Dies bedeutet, dass die Alternative 1 das Fenster verlässt. Der Grund dafür ist in dieser exzellenten Antwort zu erläutert, wie man Date zu LocalDate konvertiert .

  

Trotz seines Namens repräsentiert java.util.Date einen Augenblick auf der Zeitlinie, kein "Datum". Die tatsächlichen Daten, die innerhalb des Objekts gespeichert werden, sind eine lange Anzahl von Millisekunden seit 1970-01-01T00: 00Z (Mitternacht zu Beginn von 1970 GMT / UTC).

     

Die äquivalente Klasse zu java.util.Date in JSR-310 ist Instant, daher gibt es eine bequeme Methode toInstant (), um die Konvertierung bereitzustellen.

Also, ein Date kann in ein Instant umgewandelt werden, aber das hat uns nicht geholfen, oder?

Alternative 2 erweist sich jedoch als erfolgreich. Konvertiere die Instant in eine LocalDate und benutze dann die YearMonth.from(TemporalAccessor) -Methode.

%Vor%

Die Ausgabe ist (seit der Code im Januar 2015 ausgeführt wurde;):

  

JahrMonat: 2015-01

    
wassgren 09.01.2015, 07:26
quelle

Tags und Links