Isn’t there a convenient way of getting from a java.util.Date to a XMLGregorianCalendar?
I should like to take a step back and a modern look at this 10 years old question. The classes mentioned,
XMLGregorianCalendar, are old now. I challenge the use of them and offer alternatives.
Datewas always poorly designed and is more than 20 years old. This is simple: don’t use it.
XMLGregorianCalendaris old too and has an old-fashioned design. As I understand it, it was used for producing dates and times in XML format for XML documents. Like
2009-05-07T17:05:45.678Z. These formats agree well enough with ISO 8601 that the classes of java.time, the modern Java date and time API, can produce them, which we prefer.
No conversion necessary
For many (most?) purposes the modern replacement for a
Date will be an
Instant is a point in time (just as a
Instant yourInstant = // ... System.out.println(yourInstant);
An example output from this snippet:
It’s the same as the latter of my example
XMLGregorianCalendar strings above. As most of you know, it comes from
Instant.toString being implicitly called by
System.out.println. With java.time, in many cases we don’t need the conversions that in the old days we made between
XMLGregorianCalendar and other classes (in some cases we do need conversions, though, I am showing you a couple in the next section).
Controlling the offset
Date nor in
Instant has got a time zone nor a UTC offset. The previously accepted and still highest voted answer by Ben Noland uses the JVMs current default time zone for selecting the offset of the
XMLGregorianCalendar. To include an offset in a modern object we use an
OffsetDateTime. For example:
ZoneId zone = ZoneId.of("America/Asuncion"); OffsetDateTime dateTime = yourInstant.atZone(zone).toOffsetDateTime(); System.out.println(dateTime);
Again this conforms with XML format. If you want to use the current JVM time zone setting again, set
What if I absolutely need an XMLGregorianCalendar?
There are more ways to convert
XMLGregorianCalendar. I will present a couple, each with its pros and cons. First, just as an
XMLGregorianCalendar produces a string like
2009-05-07T17:05:45.678Z, it can also be built from such a string:
String dateTimeString = yourInstant.toString(); XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTimeString); System.out.println(date2);
Pro: it’s short and I don’t think it gives any surprises. Con: To me it feels like a waste formatting the instant into a string and parsing it back.
ZonedDateTime dateTime = yourInstant.atZone(zone); GregorianCalendar c = GregorianCalendar.from(dateTime); XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c); System.out.println(date2);
Pro: It’s the official conversion. Controlling the offset comes naturally. Con: It goes through more steps and is therefore longer.
What if we got a Date?
If you got an old-fashioned
Date object from a legacy API that you cannot afford to change just now, convert it to
Instant i = yourDate.toInstant(); System.out.println(i);
Output is the same as before:
If you want to control the offset, convert further to an
OffsetDateTime in the same way as above.
If you’ve got an old-fashioned
Date and absolutely need an old-fashioned
XMLGregorianCalendar, just use the answer by Ben Noland.
- Oracle tutorial: Date Time explaining how to use java.time.
- XSD Date and Time Data Types on W3Schools.
- Wikipedia article: ISO 8601