From XMLGregorianCalendar to Date / Calendar adds extra time / unwanted

I am developing a client for a web service that provides (.wsdl) a contract that requires the yyyy-MM-dd format for 1 in the request parameters, however the automatically generated POJOS based on .wsdl creates a date attribute as an XMLGregorianCalendar Type.


My problem is NOT converted to or from XMLGregorianCalendar, see my utility below:

public static XMLGregorianCalendar toXMLGregorianCalendar(Calendar c){ GregorianCalendar gc = new GregorianCalendar(); gc.setTimeInMillis(c.getTimeInMillis()); XMLGregorianCalendar xc= null; try { xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc); } catch (DatatypeConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return xc; } 

My problem comes from XMLGregorianCalendar in Date / Calendar adds extra temporary / unwanted data to my yyyy-MM-dd when calling calendar.getTime ();

In a specific code segment, I need to go from XMLGregorianCalendar to date

 if (repairOrderType.getCloseDate() != null) { LOG.debug("ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() BEFORE:" + repairOrderType.getCloseDate()); String date = repairOrderType.getCloseDate().getYear() + "-" + repairOrderType.getCloseDate().getMonth() + "-" + repairOrderType.getCloseDate().getDay(); //Approach #1, trying to remove hour,minute,sec values by calendar.clear() method , not successful Calendar calendar = Calendar.getInstance(); calendar.set(repairOrderType.getCloseDate().getYear(), repairOrderType.getCloseDate().getMonth(), repairOrderType.getCloseDate().getDay()); calendar.clear(Calendar.HOUR); calendar.clear(Calendar.MINUTE); calendar.clear(Calendar.SECOND); calendar.clear(Calendar.MILLISECOND); /*Approach#2 , trying to remove hour,minute,sec values using SimpleDateFormat , * also not successful. SimpleDateFormat or DateFormat are use to format String output NOT remove internal data * DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); Calendar calendar = formatter.getCalendar(); calendar.set(repairOrderType.getCloseDate().getYear(), repairOrderType.getCloseDate().getMonth(), repairOrderType.getCloseDate().getDay()); */ LOG.debug("ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() AFTER:" + calendar.getTime()); repairOrder.setCloseDate(calendar.getTime()); } 

Output:

27-November-2012 18: 10: 39.743 DEBUG com.tms.owners.integration.nsh.mapping.ServiceHistoryMapper - ServiceHistoryMapper, processRepairOrders (), repairOrderType.getCloseDate () BEFORE: 2012-04-30

27-Nov-2012 18: 10: 51.413 DEBUG com.tms.owners.integration.nsh.mapping.ServiceHistoryMapper - ServiceHistoryMapper, processRepairOrders (), repairOrderType.getCloseDate () AFTER: Wed May 30 18:00: 00 PDT 2012

As you can see above BEFORE the date before: 2012-04-30 and AFTER the date May 30, 18:00:00 PDT 2012 with the unwanted hours "18:00:00 PDT".


Below is my XML request request sent to the service:

 <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <ns4:VehicleServiceHistoryDetails xmlns="urn:tms.toyota.com/Components" xmlns:ns2="urn://esb.ari.xxxxxx.com/2008/12/10/schemas/common/Customer" xmlns:ns3="urn:incentives.ari.xxxxxx.com/StandardHeader" xmlns:ns4="urn://esb.ari.xxxxxx.com/2008/12/10/schemas/History" xmlns:ns5="http://ice.ari.xxxxxx.com/EMF" xmlns:ns6="urn:ari.xxxxxx.com/rtmheader"> <ns5:ApplicationArea> <ns5:CreationDateTime>2012-11-27T18:11:23.071-08:00 </ns5:CreationDateTime> <ns5:Sender /> <ns5:UserArea /> </ns5:ApplicationArea> <ns4:VehicleServiceHistoryDataArea> <ns4:VehicleServiceHistoryHeader> <ns3:TimeStamp>2012-11-27T18:11:23.071-08:00</ns3:TimeStamp> <ns3:SourceSystem>TOO</ns3:SourceSystem> <ns4:SourceKey>TOY1TWXE</ns4:SourceKey> </ns4:VehicleServiceHistoryHeader> <ns4:VehicleServiceHistory> <ns4:VIN>XXXXXXXXXXXXXXXX</ns4:VIN> <ns4:RepairOrder> <ns2:RepairOrderDealer> <DealerNumber>29059</DealerNumber> </ns2:RepairOrderDealer> <ns2:RepairOrderNumber>0088745</ns2:RepairOrderNumber> <ns2:CloseDate>2012-05-30-07:00</ns2:CloseDate> </ns4:RepairOrder> </ns4:VehicleServiceHistory> </ns4:VehicleServiceHistoryDataArea> </ns4:VehicleServiceHistoryDetails> </S:Body> </S:Envelope> 

You can see in the xml request at 2012-05-30-07: 00 that the additional data "-07: 00" is added, I just want 2012-05-30.

thanks

+7
source share
6 answers

In the context of XML data types, an XMLGregorianCalendar is created using the factory methods in javax.xml.datatype.DatatypeFactory, which appears to have a newXMLGregorianCalendarDate (int year, int month, int day, int timezone) method;


So, I created a useful method:

 public static XMLGregorianCalendar toXMLGregorianCalendarDateOnly(Calendar c){ GregorianCalendar gc = new GregorianCalendar(); gc.setTimeInMillis(c.getTimeInMillis()); XMLGregorianCalendar xc= null; try { xc = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(gc.get(Calendar.YEAR),Calendar.MONTH,Calendar.DAY_OF_MONTH,DatatypeConstants.FIELD_UNDEFINED); } catch (DatatypeConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return xc; } 

Now the problem is solved, we get the desired yyyy-MM-ddd.

+5
source

You can also write it as follows, which is more readable:

 GregorianCalendar gc = new GregorianCalendar(); gc.setTimeInMillis(c.getTimeInMillis()); XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc); calendar.setMillisecond(DatatypeConstants.FIELD_UNDEFINED); calendar.setTimezone(DatatypeConstants.FIELD_UNDEFINED); 
+3
source

I used the code below to solve the same problem.

 public static XMLGregorianCalendar toXMLGregorianCalendarWithoutTimeStamp(String date) { Date mDate = null; GregorianCalendar cal = new GregorianCalendar(); XMLGregorianCalendar xmlGregorianCalendar; DateFormat df = new SimpleDateFormat("dd-MM-yyyy"); try { mDate = df.parse(date); cal.setTime(mDate); xmlGregorianCalendar = DatatypeFactory.newInstance() .newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH), DatatypeConstants.FIELD_UNDEFINED); return xmlGregorianCalendar; } catch (DatatypeConfigurationException e) { LOGGER.error("Error in getCustomerCDRResponse Date Formate Type Configuartion :: " + e); } catch (ParseException e) { LOGGER.error("Error in getCustomerCDRResponse Date Parsing :: " + e); } return null; } 
0
source

try it.

 Date dob=null; DateFormat df=new SimpleDateFormat("dd/MM/yyyy"); dob=df.parse( "10/02/2014 11:15:00" ); GregorianCalendar cal = new GregorianCalendar(); cal.setTime(dob); XMLGregorianCalendar xmlDate3 = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH),DatatypeConstants.FIELD_UNDEFINED); System.out.println(xmlDate3); 
0
source

If you use javax.xml.bind.Marshaller to prepare the SOAP body, then the root of the unwanted behavior is in your xlmns: ns2. The ns2: CloseDate field is of type (or another type that includes date and time):

 {http://www.w3.org/2001/XMLSchema}dateTime 

change it to (or another type of date without hours and minutes):

 {http://www.w3.org/2001/XMLSchema}date 

If you do not control this xlmns, just accept that your CloseDate should have a time defined. Without it, the web service would call a disproportionate temporary declaration (I don’t know the exact value, but I set it to 0:00)

0
source

I also have some problems with Apache CXF and XML Marshalling.

I was able to write a simple date, causing the unwanted values ​​to be FIELD_UNDEFINED :

 //Init 'GregorianCalendar' and 'XMLGregorianCalendar' for the demo GregorianCalendar gregorianCalendar = new GregorianCalendar(); gregorianCalendar.setTime(new Date()); XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar); //Following 'setXxxx()' is the trick here xmlGregorianCalendar.setTimezone(DatatypeConstants.FIELD_UNDEFINED); xmlGregorianCalendar.setMillisecond(DatatypeConstants.FIELD_UNDEFINED); xmlGregorianCalendar.setSecond(DatatypeConstants.FIELD_UNDEFINED); xmlGregorianCalendar.setMinute(DatatypeConstants.FIELD_UNDEFINED); xmlGregorianCalendar.setHour(DatatypeConstants.FIELD_UNDEFINED); //Marshaller should call toXMLFormat() System.out.println(xmlGregorianCalendar.toXMLFormat()); 

Worked with Apache CXF version 3.7.7 .

0
source

All Articles