EDate function implementation from Detlef Brendle from bug #54508

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1442392 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2013-02-04 22:01:55 +00:00
parent b68b2068d4
commit 37c76d9b28
3 changed files with 96 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.function.FunctionMetadata; import org.apache.poi.ss.formula.function.FunctionMetadata;
import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
import org.apache.poi.ss.formula.functions.EDate;
import org.apache.poi.ss.formula.functions.FreeRefFunction; import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.apache.poi.ss.formula.functions.Sumifs; import org.apache.poi.ss.formula.functions.Sumifs;
import org.apache.poi.ss.formula.udf.UDFFinder; import org.apache.poi.ss.formula.udf.UDFFinder;
@ -99,7 +100,7 @@ public final class AnalysisToolPak implements UDFFinder {
r(m, "DOLLARDE", null); r(m, "DOLLARDE", null);
r(m, "DOLLARFR", null); r(m, "DOLLARFR", null);
r(m, "DURATION", null); r(m, "DURATION", null);
r(m, "EDATE", null); r(m, "EDATE", EDate.instance);
r(m, "EFFECT", null); r(m, "EFFECT", null);
r(m, "EOMONTH", null); r(m, "EOMONTH", null);
r(m, "ERF", null); r(m, "ERF", null);

View File

@ -0,0 +1,43 @@
package org.apache.poi.ss.formula.functions;
import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.usermodel.DateUtil;
import java.util.Calendar;
import java.util.Date;
public class EDate implements FreeRefFunction {
public static final FreeRefFunction instance = new EDate();
@Override
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
if (args.length != 2) {
return ErrorEval.VALUE_INVALID;
}
try {
double startDateAsNumber = getValue(args[0]);
NumberEval offsetInYearsValue = (NumberEval) args[1];
int offsetInMonthAsNumber = (int) offsetInYearsValue.getNumberValue();
Date startDate = DateUtil.getJavaDate(startDateAsNumber);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
calendar.add(Calendar.MONTH, offsetInMonthAsNumber);
return new NumberEval(DateUtil.getExcelDate(calendar.getTime()));
} catch (EvaluationException e) {
return e.getErrorEval();
}
}
private double getValue(ValueEval arg) throws EvaluationException {
if (arg instanceof NumberEval) {
return ((NumberEval) arg).getNumberValue();
}
if (arg instanceof RefEval) {
ValueEval innerValueEval = ((RefEval) arg).getInnerValueEval();
return ((NumberEval) innerValueEval).getNumberValue();
}
throw new EvaluationException(ErrorEval.REF_INVALID);
}
}

View File

@ -0,0 +1,51 @@
package org.apache.poi.ss.formula.functions;
import junit.framework.TestCase;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.ErrorConstants;
import java.util.Calendar;
import java.util.Date;
public class TestEDate extends TestCase{
public void testEDateProperValues() {
EDate eDate = new EDate();
NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(1000), new NumberEval(0)}, null);
assertEquals(1000d, result.getNumberValue());
}
public void testEDateInvalidValues() {
EDate eDate = new EDate();
ErrorEval result = (ErrorEval) eDate.evaluate(new ValueEval[]{new NumberEval(1000)}, null);
assertEquals(ErrorConstants.ERROR_VALUE, result.getErrorCode());
}
public void testEDateIncrease() {
EDate eDate = new EDate();
Date startDate = new Date();
int offset = 2;
NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(DateUtil.getExcelDate(startDate)), new NumberEval(offset)}, null);
Date resultDate = DateUtil.getJavaDate(result.getNumberValue());
Calendar instance = Calendar.getInstance();
instance.setTime(startDate);
instance.add(Calendar.MONTH, offset);
assertEquals(resultDate, instance.getTime());
}
public void testEDateDecrease() {
EDate eDate = new EDate();
Date startDate = new Date();
int offset = -2;
NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(DateUtil.getExcelDate(startDate)), new NumberEval(offset)}, null);
Date resultDate = DateUtil.getJavaDate(result.getNumberValue());
Calendar instance = Calendar.getInstance();
instance.setTime(startDate);
instance.add(Calendar.MONTH, offset);
assertEquals(resultDate, instance.getTime());
}
}