0

While working with legacy code not yet updated for the modern java.time classes, I need to convert a ZonedDateTime to XMLGregorianCalendar. So I thought I'd go by way of GregorianCalendar, calling GregorianCalendar.from( ZonedDateTime ).

I see methods for going from XMLGregorianCalendar to GregorianCalendar: XMLGregorianCalendar::toGregorianCalendar.

➥ I need the opposite, going from GregorianCalendar to XMLGregorianCalendar.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Basil, this seems to be answered at https://stackoverflow.com/q/835889/ . Any reason I shouldn't close this as duplicate? – Dawood ibn Kareem Dec 09 '19 at 22:48
  • @DawoodsaysreinstateMonica Not a duplicate. A `java.util.Date` is not a `GregorianCalendar`. A `Date` is always in UTC, while a `GregorianCalendar` has a time zone. But I notice there is a kernel of an Answer [there](https://stackoverflow.com/a/56313273/642706) for here. I'll write an Answer now. – Basil Bourque Dec 09 '19 at 23:01
  • 1
    Sasuke's answer on that other question seems to be just what you wanted. – Dawood ibn Kareem Dec 09 '19 at 23:03
  • @DawoodsaysreinstateMonica Well, yes indeed, I see that one now. Ironically, [that Answer](https://stackoverflow.com/a/835983/642706) is *not* a correct answer on [that Question](https://stackoverflow.com/q/835889/642706) but is to mine here. So, again, this Question here is *not* a duplicate of [that Question](https://stackoverflow.com/q/835889/642706). – Basil Bourque Dec 09 '19 at 23:08

2 Answers2

1

DatatypeFactory.newInstance().newXMLGregorianCalendar( … )

While neither the XMLGregorianCalendar nor GregorianCalendar classes offer the conversion method you need, there is a workaround.

A javax.xml.datatype.DatatypeFactory object can convert from GregorianCalendar to XMLGregorianCalendar by calling its newXMLGregorianCalendar method.

XMLGregorianCalendar xmlGregCal = 
        DatatypeFactory
        .newInstance()
        .newXMLGregorianCalendar( gregCal ) 
;

To complete the entire cascade you mentioned, from java.time.ZonedDateTime to GregorianCalendar to XMLGregorianCalendar.

XMLGregorianCalendar xmlGregCal = 
        DatatypeFactory
        .newInstance()
        .newXMLGregorianCalendar( 
            GregorianCalendar
            .from(
                myZonedDateTime
            )
        ) 
;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Shouldn't people use the solution mentioned here instead: https://stackoverflow.com/a/62659961/6762888 which skips creating a newInstance() of DataTypeFactory which is expensive? – A.D Aug 19 '21 at 07:12
  • @A.D No, we should *not* use the `XMLGregorianCalendarImpl` class seen in [that Answer](https://stackoverflow.com/a/62659961/642706). There is no such class listed in the [Javadoc for the public API of Java](https://docs.oracle.com/en/java/javase/19/docs/api/index.html). The public API provides [`XMLGregorianCalendar`](https://download.java.net/java/early_access/jdk19/docs/api/java.xml/javax/xml/datatype/XMLGregorianCalendar.html) but not `XMLGregorianCalendarImpl`. That class in an internal implementation detail, subject to change or removal. – Basil Bourque Jan 25 '23 at 20:22
  • @A.D Furthermore, [the Javadoc](https://download.java.net/java/early_access/jdk19/docs/api/java.xml/javax/xml/datatype/XMLGregorianCalendar.html#%3Cinit%3E()) tells us explicitly to "Always use the `DatatypeFactory` to construct an instance of `XMLGregorianCalendar`". – Basil Bourque Jan 25 '23 at 20:23
1

Another way is the following:

import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
    

GregorianCalendar calendar = new GregorianCalendar();
XMLGregorianCalendar xmlGregorianCalendar = new XMLGregorianCalendarImpl(calendar);