}
@Override
protected <U extends IValue> Result<U> subtractDateTime(DateTimeResult that) {
IDateTime dStart = this.getValue();
Calendar startCal = Calendar.getInstance();
startCal.setTimeInMillis(dStart.getInstant());
IDateTime dEnd = that.getValue();
Calendar endCal = Calendar.getInstance();
endCal.setTimeInMillis(dEnd.getInstant());
if (dStart.isDate()) {
if (dEnd.isDate()) {
return makeResult(Duration,
VF.constructor(DateTimeResult.duration,
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.YEAR)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MONTH)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.DAY_OF_MONTH)),
VF.integer(0),
VF.integer(0),
VF.integer(0),
VF.integer(0)),
ctx);
} else if (dEnd.isTime()) {
throw RuntimeExceptionFactory.invalidUseOfTimeException("Cannot determine the duration between a date with no time and a time with no date.", ctx.getCurrentAST(), null);
} else {
throw RuntimeExceptionFactory.invalidUseOfDateTimeException("Cannot determine the duration between a date with no time and a datetime.", ctx.getCurrentAST(), null);
}
} else if (dStart.isTime()) {
if (dEnd.isTime()) {
return makeResult(Duration,
VF.constructor(DateTimeResult.duration,
VF.integer(0),
VF.integer(0),
VF.integer(0),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.HOUR_OF_DAY)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MINUTE)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.SECOND)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MILLISECOND))),
ctx);
} else if (dEnd.isDate()) {
throw RuntimeExceptionFactory.invalidUseOfDateException("Cannot determine the duration between a time with no date and a date with no time.", ctx.getCurrentAST(), null);
} else {
throw RuntimeExceptionFactory.invalidUseOfDateTimeException("Cannot determine the duration between a time with no date and a datetime.", ctx.getCurrentAST(), null);
}
} else {
if (dEnd.isDateTime()) {
return makeResult(Duration,
VF.constructor(DateTimeResult.duration,
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.YEAR)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MONTH)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.DAY_OF_MONTH)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.HOUR_OF_DAY)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MINUTE)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.SECOND)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MILLISECOND))),
ctx);
} else if (dEnd.isDate()) {
throw RuntimeExceptionFactory.invalidUseOfDateException("Cannot determine the duration between a datetime and a date with no time.", ctx.getCurrentAST(), null);
} else {
throw RuntimeExceptionFactory.invalidUseOfTimeException("Cannot determine the duration between a datetime and a time with no date.", ctx.getCurrentAST(), null);