I have a String date I am converting to a XMLGregorianCalendar
. The below code converts it with no errors. However, the system I pass the date to, gets the error reported below.
The following XMLGregorianCalendar
works:
The following XMLGregorianCalendar
does not work (the code below converts it to this):
Question
How do I convert the string to the required format?
public static void main(String []args){
try {
String commenceTOString = "2021-06-30 05:00:00";
java.util.Date dateCommence = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(commenceTOString);
System.out.println(dateCommence);
java.util.GregorianCalendar c = new java.util.GregorianCalendar();
c.setTime(dateCommence);
javax.xml.datatype.XMLGregorianCalendar commence = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
System.out.println(commence);
} catch (Exception e) {
e.printStackTrace();
}
}
Error
E: Message validation failed. Errors: [cvc-pattern-valid: Value '2021-06-30T06:30:00.000+02:00' is not facet-valid with respect to pattern '(((((0[1-9])|(1[0-2]))-((0[1-9])|(1\d)|(2[0-9])))|((((0[13578])|(1[02]))-31)|(((0[1,3-9])|(1[0-2]))-30)))|(((19|20)(([02468][048])|([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0[1-9])|(1[0-2]))-((0[1-9])|(1\d)|(2[0-8])))|((((0[13578])|(1[02]))-31)|(((0[1,3-9])|(1[0-2]))-(29|30)))))T([0-1][0-9]|[2][0-3])(:([0-5][0-9])){1,2}' for type 'dateTime'.cvc-attribute.3: The value '2021-06-30T06:30:00.000+02:00' of attribute 'DepartureDateTime' on element 'FlightSegment' is not valid with respect to its type, 'dateTime'.]. http://www.elleipsis.com/booking/exception/35a8ac87-6743-4719-9504-a8a17a1a0471
There are many ways to do this. Generally I recommend that you use java.time for your date and time work, also when there is no direct conversion between java.time classes and
XMLGregorianCalendar
.The hack
The hack is simply to edit the
T
into the string thatXMLGregorianCalendar
expects to be there and then parse the modified string directly. Then we neither need java.time norDate
norSimpleDateFormat
.Output:
Convert via String
Parse into
LocalDateTime
, format into a string in the formatXMLGregorianCalendar
knows and let theDatatypeFactory
parse again:Output is the same as before.
Convert via numbers
Though a few lines longer this is the conceptually simple conversion: transfer each field from
LocalDateTime
toXMLGregorianCalendar
.Output is still the same.
Convert via GregorianCalendar
I believe that this is the official conversion: convert to
ZonedDateTime
toGregorianCalendar
and finally toXMLGregorianCalendar
. We need to set the unwanted field toFIELD_UNDEFINED
just as in your own answer.Link
Oracle tutorial: Date Time explaining how to use java.time.