How do I subtract two XmlGregorianCalendar objects to create one Duration object?

The accepted answer only gives the results in millis resolution but XmlGregorianCalendar allows infinite precision. We had to solve the problem for µS resolution. I did it by converting to big decimal and using getFractionalSeconds. see below

 public static BigDecimal convertXMLGregorianToSecondsAndFractionalSeconds(XMLGregorianCalendar xgc){
    long ms = xgc.toGregorianCalendar().getTimeInMillis();
    long secs = ms / 1000l;
    BigDecimal decValue = BigDecimal.valueOf(secs);
    BigDecimal fracSects = xgc.getFractionalSecond();
    decValue = decValue.add(fracSects);
    return decValue;
}

 @Test
public void testSubtraction() throws Exception {
    XMLGregorianCalendar xgc1 =  DatatypeFactory.newInstance().newXMLGregorianCalendar("2015-05-22T16:28:40.317123-04:00");
    XMLGregorianCalendar xgc2 =  DatatypeFactory.newInstance().newXMLGregorianCalendar("2015-05-22T16:28:40.917124-04:00");
    BigDecimal bd1 = MathUtils.convertXMLGregorianToSecondsAndFractionalSeconds(xgc1);
    BigDecimal bd2 = MathUtils.convertXMLGregorianToSecondsAndFractionalSeconds(xgc2);
    BigDecimal result = bd2.subtract(bd1);
    Assert.assertTrue(result.equals(new BigDecimal("0.600001")));
}  

That should be:

DatatypeFactory.newDuration(xgc2.toGregorianCalendar().getTimeInMillis() - xgc1.toGregorianCalendar().getTimeInMillis())

Tags:

Java