Wie kann ich am besten ein java.util.Date
in ein Java 8 java.time.YearMonth
konvertieren?Wie konvertiert man java.util.Date in Java8 java.time.YearMonth
Leider wirft die folgenden ein DateTimeException
:
YearMonth yearMonth = YearMonth.from(date.toInstant());
Ergebnisse in:
java.time.DateTimeException: Unable to obtain YearMonth from TemporalAccessor: 2015-01-08T14:28:39.183Z of type java.time.Instant
at java.time.YearMonth.from(YearMonth.java:264)
...
ich diese Funktionalität benötigen, da ich YearMonth
Werte in einer Datenbank mit JPA speichern möchten. Derzeit JPA nicht YearMonth
‚s nicht unterstützt, also habe ich mit folgendem YearMonthConverter kommen (Importe weggelassen):
// TODO (future): delete when next version of JPA (i.e. Java 9?) supports YearMonth. See https://java.net/jira/browse/JPA_SPEC-63
@Converter(autoApply = true)
public class YearMonthConverter implements AttributeConverter<YearMonth, Date> {
@Override
public Date convertToDatabaseColumn(YearMonth attribute) {
// uses default zone since in the end only dates are needed
return attribute == null ? null : Date.from(attribute.atDay(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
}
@Override
public YearMonth convertToEntityAttribute(Date dbData) {
// TODO: check if Date -> YearMonth can't be done in a better way
if (dbData == null) return null;
Calendar calendar = Calendar.getInstance();
calendar.setTime(dbData);
return YearMonth.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1);
}
}
Gibt es nicht eine bessere (sauberere, kürzer) -Lösung (für beide Richtungen)?
persönlich Mapping vermeide ich würde 'java.util.Date 'weil a) es nicht 'java.sql. *' - Typ ist, b) implizite Zeitzone enthält (schlechte Leistung und unscharfe Verwendung der Systemzeitzone), c) SQL definiert keinen solchen Typ für Jahr-Monat. Bessere Karte 'YearMonth' auf ganzzahlige mit [PROLEPTIC_MONTH] (http://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoField.html#PROLEPTIC_MONTH) –
@MenoHochschild: Das ist eine gute Idee, - Einziger Nachteil ist, dass es nicht lesbar ist, wenn man sich die Datenbank ansieht. Kein Problem in meinem Fall ... – Sebastian
Nun, nur eine Ganzzahl ist nicht lesbar für die direkte Ansicht von db-Inhalten, aber beachten Sie, dass die Zuordnung zu juDate das visualisierte Datum und den Monat (wie ein db-Administrator sieht) aufgrund der Zeitzone ändern kann Konvertierungen und db/server-Einstellungen. –