Gibt es nicht eine bequeme Möglichkeit, von einem java.util.Date zu einem XMLGregorianCalendar zu gelangen?
Antworten
Zu viele Anzeigen?Ich möchte einen Schritt zurückgehen und einen modernen Blick auf diese 10 Jahre alte Frage werfen. Die erwähnten Klassen, Date
y XMLGregorianCalendar
, sind jetzt alt. Ich stelle ihre Verwendung in Frage und biete Alternativen an.
Date
war schon immer schlecht konzipiert und ist mehr als 20 Jahre alt. Es ist ganz einfach: Verwenden Sie es nicht.XMLGregorianCalendar
ist ebenfalls alt und hat ein altmodisches Design. Soweit ich weiß, wurde es für die Erstellung von Datums- und Zeitangaben im XML-Format für XML-Dokumente verwendet. Wie2009-05-07T19:05:45.678+02:00
oder2009-05-07T17:05:45.678Z
. Diese Formate stimmen so gut mit ISO 8601 überein, dass die Klassen von java.time, der modernen Java-API für Datum und Uhrzeit, sie erzeugen können, was wir bevorzugen.
Keine Umwandlung erforderlich
Für viele (die meisten?) Zwecke ist der moderne Ersatz für eine Date
wird ein Instant
. Eine Instant
ist ein Zeitpunkt (ebenso wie ein Date
ist).
Instant yourInstant = // ...
System.out.println(yourInstant);
Ein Beispiel für die Ausgabe dieses Schnipsels:
2009-05-07T17:05:45.678Z
Es ist dasselbe wie in meinem letzten Beispiel XMLGregorianCalendar
Strings oben. Wie die meisten von Ihnen wissen, stammt es aus Instant.toString
wird implizit aufgerufen von System.out.println
. Mit java.time brauchen wir in vielen Fällen nicht mehr die Konvertierungen, die wir früher zwischen Date
, Calendar
, XMLGregorianCalendar
und andere Klassen (in einigen Fällen sind jedoch Konvertierungen erforderlich, von denen ich Ihnen im nächsten Abschnitt einige vorstelle).
Kontrolle des Offsets
Weder ein Date
noch in Instant
hat weder eine Zeitzone noch einen UTC-Offset. Die zuvor akzeptierte und immer noch am häufigsten gewählte Antwort von Ben Noland verwendet die aktuelle Standardzeitzone der JVM für die Auswahl des Offsets der XMLGregorianCalendar
. Um einen Offset in ein modernes Objekt einzubinden, verwenden wir eine OffsetDateTime
. Zum Beispiel:
ZoneId zone = ZoneId.of("America/Asuncion");
OffsetDateTime dateTime = yourInstant.atZone(zone).toOffsetDateTime();
System.out.println(dateTime);
2009-05-07T13:05:45.678-04:00
Auch dies entspricht dem XML-Format. Wenn Sie wieder die aktuelle JVM-Zeitzoneneinstellung verwenden wollen, setzen Sie zone
a ZoneId.systemDefault()
.
Was, wenn ich unbedingt einen XMLGregorianCalendar brauche?
Es gibt noch weitere Möglichkeiten der Konvertierung Instant
a XMLGregorianCalendar
. Ich werde ein paar davon vorstellen, jede mit ihren Vor- und Nachteilen. Erstens, nur als XMLGregorianCalendar
ergibt eine Zeichenkette wie 2009-05-07T17:05:45.678Z
kann sie auch aus einer solchen Zeichenkette gebildet werden:
String dateTimeString = yourInstant.toString();
XMLGregorianCalendar date2
= DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTimeString);
System.out.println(date2);
2009-05-07T17:05:45.678Z
Pro: Er ist kurz und ich glaube nicht, dass er irgendwelche Überraschungen bietet. Contra: Mir kommt es wie eine Verschwendung vor, den Augenblick in eine Zeichenkette zu formatieren und sie wieder zu parsen.
ZonedDateTime dateTime = yourInstant.atZone(zone);
GregorianCalendar c = GregorianCalendar.from(dateTime);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
System.out.println(date2);
2009-05-07T13:05:45.678-04:00
Pro: Es ist die offizielle Umrechnung. Die Kontrolle des Offsets ist selbstverständlich. Nachteil: Es sind mehr Schritte erforderlich und es dauert daher länger.
Was wäre, wenn wir ein Date hätten?
Wenn Sie eine altmodische Date
Objekt aus einer veralteten API, die Sie jetzt nicht ändern können, konvertieren Sie es in Instant
:
Instant i = yourDate.toInstant();
System.out.println(i);
Die Ausgabe ist dieselbe wie zuvor:
2009-05-07T17:05:45.678Z
Wenn Sie den Versatz kontrollieren wollen, konvertieren Sie weiter in eine OffsetDateTime
auf die gleiche Weise wie oben.
Wenn Sie eine altmodische Date
und brauchen unbedingt eine altmodische XMLGregorianCalendar
verwenden Sie einfach die Antwort von Ben Noland.
Links
- Oracle-Lehrgang: Datum Uhrzeit erklärt, wie man java.time.
- XSD Datums- und Zeitdatentypen auf W3Schools.
- Wikipedia-Artikel: ISO 8601
Ein einzeiliges Beispiel mit Joda-Time Bibliothek:
XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(new DateTime().toGregorianCalendar());
Kredit an Nicolas Mommaerts aus seinem Kommentar in die akzeptierte Antwort .
Sehen Sie sich diesen Code an :-
/* Create Date Object */
Date date = new Date();
XMLGregorianCalendar xmlDate = null;
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
try{
xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("XMLGregorianCalendar :- " + xmlDate);
Sie können ein vollständiges Beispiel sehen aquí
Meine Lösung
public static XMLGregorianCalendar DateToXMLGregorianCalendar(Date date) {
GregorianCalendar gregoriancalendar = new GregorianCalendar();
gregoriancalendar.setTime(date);
XMLGregorianCalendar xmlGregorianCalendar = new XMLGregorianCalendarImpl(gregoriancalendar);
return xmlGregorianCalendar;
}