Benjamin Tenne created XERCESJ-1669:
---------------------------------------
Summary: Duration arithmetic can give the wrong result when
fractional seconds are used
Key: XERCESJ-1669
URL: https://issues.apache.org/jira/browse/XERCESJ-1669
Project: Xerces2-J
Issue Type: Bug
Affects Versions: 2.11.0
Reporter: Benjamin Tenne
Priority: Minor
Consider the following:
{code}
DatatypeFactory fac = DatatypeFactory.newInstance();
Duration a1 = fac.newDuration("PT4H");
Duration a2 = fac.newDuration("PT1S");
System.out.println(a1.subtract(a2));
{code}
As expected, subtracting a second from four hours results in:
PT3H59M59S
However, if fractional seconds are used...
{code}
DatatypeFactory fac = DatatypeFactory.newInstance();
Duration a1 = fac.newDuration("PT4H");
Duration a2 = fac.newDuration("PT1.0S");
System.out.println(a1.subtract(a2));
{code}
This gives the unexpected result of:
PT39H59M5.0S
This appears to be due to a bug in DurationImpl. The subtraction gives an
intermediate result of PT4H-1.0S, which is then normalized in the alignSigns
method to eliminate the negative seconds. The logic that calculates "How may
minutes do we need to borrow from the minutes column to eliminate the negative
seconds?" should result in 1, but actually results in 0.1. This is due to the
use of the divide(BigDecimal divisor, int roundingMode) method. The code
appears to be expecting this method to return an integer, but it doesn't; it
inherits the scale of the original BigDecimal, which in this case has one
decimal place.
I believe the fix would be to call the three-arg method that takes a scale,
setting it to zero, thus forcing the desired behaviour of getting an integer
back:
{code}
// compute the number of unit that needs to be borrowed.
BigDecimal borrow =
buf[i].abs().divide(
FACTORS[i - 1],
0, // Division must result in an integer
BigDecimal.ROUND_UP);
{code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]