long absoluteDifference = Math.abs(difference);
// Required for thread-safety
List<TimeUnit> localUnits = getUnits();
DurationImpl result = new DurationImpl();
for (int i = 0; i < localUnits.size(); i++)
{
TimeUnit unit = localUnits.get(i);
long millisPerUnit = Math.abs(unit.getMillisPerUnit());
long quantity = Math.abs(unit.getMaxQuantity());
boolean isLastUnit = (i == localUnits.size() - 1);
if ((0 == quantity) && !isLastUnit)
{
quantity = localUnits.get(i + 1).getMillisPerUnit() / unit.getMillisPerUnit();
}
// does our unit encompass the time duration?
if ((millisPerUnit * quantity > absoluteDifference) || isLastUnit)
{
result.setUnit(unit);
if (millisPerUnit > absoluteDifference)
{
// we are rounding up: get 1 or -1 for past or future
result.setQuantity(getSign(difference));
result.setDelta(0);
}
else
{
result.setQuantity(difference / millisPerUnit);
result.setDelta(difference - result.getQuantity() * millisPerUnit);
}
break;
}
}