// These two functions are basically the same except for sign.
// And they both need to deal with sign anyway, so they share
// their code.
case ID_DATETIME_ADD_DAYTIMEDURATION:
case ID_DATETIME_SUBTRACT_DAYTIMEDURATION: {
DateTimeAttribute dateTime = (DateTimeAttribute) argValues[0];
DayTimeDurationAttribute duration = (DayTimeDurationAttribute) argValues[1];
// Decide what sign goes with duration
int sign = 1;
if (getFunctionId() == ID_DATETIME_SUBTRACT_DAYTIMEDURATION)
sign = -sign;
if (duration.isNegative())
sign = -sign;
long millis = sign * duration.getTotalSeconds();
long nanoseconds = dateTime.getNanoseconds();
nanoseconds = nanoseconds + (sign * duration.getNanoseconds());
if (nanoseconds >= 1000000000) {
nanoseconds -= 1000000000;
millis += 1000;
}
if (nanoseconds < 0) {
nanoseconds += 1000000000;
millis -= 1000;
}
millis = millis + dateTime.getValue().getTime();
attrResult = new DateTimeAttribute(new Date(millis), (int) nanoseconds, dateTime
.getTimeZone(), dateTime.getDefaultedTimeZone());
break;
}
case ID_DATETIME_ADD_YEARMONTHDURATION:
case ID_DATETIME_SUBTRACT_YEARMONTHDURATION: {
DateTimeAttribute dateTime = (DateTimeAttribute) argValues[0];
YearMonthDurationAttribute duration = (YearMonthDurationAttribute) argValues[1];
// Decide what sign goes with duration
int sign = 1;
if (getFunctionId() == ID_DATETIME_SUBTRACT_YEARMONTHDURATION)
sign = -sign;
if (duration.isNegative())
sign = -sign;
// Add (or subtract) the years and months.
Calendar cal = new GregorianCalendar();
cal.setTime(dateTime.getValue());
long years = sign * duration.getYears();
long months = sign * duration.getMonths();
if ((years > Integer.MAX_VALUE) || (years < Integer.MIN_VALUE))
return makeProcessingError("years too large");
if ((months > Integer.MAX_VALUE) || (months < Integer.MIN_VALUE))
return makeProcessingError("months too large");
cal.add(Calendar.YEAR, (int) years);
cal.add(Calendar.MONTH, (int) months);
attrResult = new DateTimeAttribute(cal.getTime(), dateTime.getNanoseconds(), dateTime
.getTimeZone(), dateTime.getDefaultedTimeZone());
break;
}
case ID_DATE_ADD_YEARMONTHDURATION:
case ID_DATE_SUBTRACT_YEARMONTHDURATION: {