return values;
}
// there are more efficient algorithms than this (especially for time only fields)
// trouble is when dealing with days and months, so we use this technique of
// adding/removing one from the larger field at a time
DateTimeField nextField = null;
while (valueToAdd > 0) {
int max = getMaximumValue(instant, values);
long proposed = values[fieldIndex] + valueToAdd;
if (proposed <= max) {
values[fieldIndex] = (int) proposed;
break;
}
if (nextField == null) {
if (fieldIndex == 0) {
throw new IllegalArgumentException("Maximum value exceeded for add");
}
nextField = instant.getField(fieldIndex - 1);
// test only works if this field is UTC (ie. local)
if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
throw new IllegalArgumentException("Fields invalid for add");
}
}
valueToAdd -= (max + 1) - values[fieldIndex]; // reduce the amount to add
values = nextField.add(instant, fieldIndex - 1, values, 1); // add 1 to next bigger field
values[fieldIndex] = getMinimumValue(instant, values); // reset this field to zero
}
while (valueToAdd < 0) {
int min = getMinimumValue(instant, values);
long proposed = values[fieldIndex] + valueToAdd;
if (proposed >= min) {
values[fieldIndex] = (int) proposed;
break;
}
if (nextField == null) {
if (fieldIndex == 0) {
throw new IllegalArgumentException("Maximum value exceeded for add");
}
nextField = instant.getField(fieldIndex - 1);
if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
throw new IllegalArgumentException("Fields invalid for add");
}
}
valueToAdd -= (min - 1) - values[fieldIndex]; // reduce the amount to add
values = nextField.add(instant, fieldIndex - 1, values, -1); // subtract 1 from next bigger field
values[fieldIndex] = getMaximumValue(instant, values); // reset this field to max value
}
return set(instant, fieldIndex, values, values[fieldIndex]); // adjusts smaller fields
}