Gibt es nicht eine bequeme Möglichkeit, von einem java.util.Date zu einem XMLGregorianCalendar zu gelangen?
601
Gibt es nicht eine bequeme Möglichkeit, von einem java.util.Date zu einem XMLGregorianCalendar zu gelangen?
ZonedDateTime
Klasse und neue Konvertierungsmethoden, die den Legacy-Klassen hinzugefügt wurden. Details in dieser Antwort von Ole VVAntworten:
Ich möchte einen Schritt zurücktreten und einen modernen Blick auf diese 10 Jahre alte Frage werfen. Die erwähnten Klassen
Date
undXMLGregorianCalendar
sind jetzt alt. Ich fordere deren Verwendung heraus und biete Alternativen an.Date
war immer schlecht gestaltet und ist mehr als 20 Jahre alt. Das ist einfach: benutze es nicht.XMLGregorianCalendar
ist auch alt und hat ein altmodisches Design. Soweit ich weiß, wurde es zum Erstellen von Datums- und Uhrzeitangaben 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 gut genug 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 Konvertierung notwendig
Für viele (die meisten?) Zwecke wird der moderne Ersatz für a
Date
einInstant
. AnInstant
ist ein Zeitpunkt (so wie aDate
ist).Eine Beispielausgabe dieses Snippets:
Es ist dasselbe wie das letztere meiner
XMLGregorianCalendar
obigen Beispielzeichenfolgen . Wie die meisten von Ihnen wissen, kommt es davon,Instant.toString
dass sie implizit von angerufen werdenSystem.out.println
. Mit java.time in vielen Fällen brauchen wir nicht die Umsetzungen , die in den alten Tagen , die wir gemacht zwischenDate
,Calendar
,XMLGregorianCalendar
und anderen Klassen (in einigen Fällen wir müssen Conversions tun, obwohl, zeige ich Ihnen ein paar im nächsten Abschnitt) .Offset steuern
Weder a
Date
noch inInstant
haben eine Zeitzone oder einen UTC-Offset. Die zuvor akzeptierte und immer noch am höchsten bewertete Antwort von Ben Noland verwendet die aktuelle Standardzeitzone der JVM zur Auswahl des Versatzes derXMLGregorianCalendar
. Um einen Versatz in ein modernes Objekt aufzunehmen, verwenden wir einOffsetDateTime
. Zum Beispiel:Auch dies entspricht dem XML-Format. Wenn Sie die aktuelle JVM-Zeitzoneneinstellung erneut verwenden möchten, setzen Sie
zone
aufZoneId.systemDefault()
.Was ist, wenn ich unbedingt einen XMLGregorianCalendar benötige?
Es gibt mehr Möglichkeiten , konvertieren
Instant
zuXMLGregorianCalendar
. Ich werde ein Paar vorstellen, jedes mit seinen Vor- und Nachteilen. Erstens kannXMLGregorianCalendar
ein String, wie er erzeugt2009-05-07T17:05:45.678Z
, auch aus einem solchen String erstellt werden:Pro: Es ist kurz und ich glaube nicht, dass es irgendwelche Überraschungen gibt. Con: Für mich fühlt es sich wie eine Verschwendung an, den Augenblick in einen String zu formatieren und ihn zurück zu analysieren.
Pro: Es ist die offizielle Konvertierung. Die Steuerung des Offsets ist selbstverständlich. Con: Es geht durch mehr Schritte und ist daher länger.
Was ist, wenn wir ein Date haben?
Wenn Sie ein altmodisches
Date
Objekt von einer Legacy-API erhalten haben, dessen Änderung Sie sich gerade nicht leisten können, konvertieren Sie es inInstant
:Die Ausgabe ist dieselbe wie zuvor:
Wenn Sie den Versatz steuern möchten, konvertieren Sie auf
OffsetDateTime
die gleiche Weise wie oben weiter in a.Wenn Sie eine altmodische haben
Date
und unbedingt eine altmodische brauchenXMLGregorianCalendar
, verwenden Sie einfach die Antwort von Ben Noland.Links
quelle
quelle
Für diejenigen, die hier landen könnten und nach der entgegengesetzten Konvertierung suchen (von
XMLGregorianCalendar
nachDate
):quelle
Hier ist eine Methode zum Konvertieren von einem GregorianCalendar in einen XMLGregorianCalendar. Ich überlasse den Teil der Konvertierung von java.util.Date in GregorianCalendar als Übung für Sie:
EDIT: Slooow :-)
quelle
Ein einzeiliges Beispiel mit der Joda-Time- Bibliothek:
Dank an Nicolas Mommaerts aus seinem Kommentar in der akzeptierten Antwort .
quelle
Ich dachte nur, ich würde meine Lösung unten hinzufügen, da die obigen Antworten nicht genau meinen Anforderungen entsprachen. Für mein XML-Schema waren separate Datums- und Uhrzeitelemente erforderlich, kein einzelnes DateTime-Feld. Der oben verwendete Standardkonstruktor XMLGregorianCalendar generiert ein DateTime-Feld
Beachten Sie, dass es einige Gothcas gibt, z. B. das Hinzufügen eines Monats zum Monat (da Java Monate von 0 zählt).
quelle
Ich hoffe, meine Codierung hier ist richtig; D Um es schneller zu machen, verwenden Sie einfach den hässlichen getInstance () -Aufruf von GregorianCalendar anstelle des Konstruktoraufrufs:
quelle
GregorianCalendar.getInstance()
ist das Äquivalent vonCalendar.getInstance()
. DasCalendar.getInstance()
kann es nicht schneller machen, weil es dasselbe verwendetnew GregorianCalendar()
, aber bevor es auch das Standardgebietsschema überprüft und stattdessen einen japanischen oder Buddish-Kalender erstellen könnte, wird es für einige glückliche Benutzer so seinClassCastException
!Angenommen, Sie dekodieren oder codieren XML und verwenden XML
JAXB
, dann ist es möglich, die dateTime-Bindung vollständig zu ersetzen und für jedes Datum im Schema etwas anderes als "XMLGregorianCalendar" zu verwenden.Auf diese Weise können Sie haben
JAXB
Sie die sich wiederholenden Dinge erledigen, während Sie die Zeit damit verbringen können, fantastischen Code zu schreiben, der Wert liefert.Beispiel für eine Jodatime
DateTime
: (Dies mit java.util.Date zu tun würde auch funktionieren - aber mit bestimmten Einschränkungen. Ich bevorzuge Jodatime und es wird aus meinem Code kopiert, damit ich weiß, dass es funktioniert ...)Und der Konverter:
Siehe hier: Wie kann XmlGregorianCalendar durch Datum ersetzt werden?
Wenn Sie gerne nur einen Moment basierend auf der Zeitzone + dem Zeitstempel zuordnen und die ursprüngliche Zeitzone nicht wirklich relevant ist,
java.util.Date
ist dies wahrscheinlich auch in Ordnung.quelle
Überprüfen Sie diesen Code: -
Das vollständige Beispiel finden Sie hier
quelle