]> source.dussan.org Git - poi.git/commitdiff
EDate function implementation from Detlef Brendle from bug #54508
authorNick Burch <nick@apache.org>
Mon, 4 Feb 2013 22:01:55 +0000 (22:01 +0000)
committerNick Burch <nick@apache.org>
Mon, 4 Feb 2013 22:01:55 +0000 (22:01 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1442392 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
src/java/org/apache/poi/ss/formula/functions/EDate.java [new file with mode: 0644]
src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java [new file with mode: 0644]

index a9343e67a3437dd4bf60f5e1d7a3f16595087457..28215641fdb632b1e9a1e45e306b71b8a7ca26f2 100644 (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.function.FunctionMetadata;
 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.Sumifs;
 import org.apache.poi.ss.formula.udf.UDFFinder;
@@ -99,7 +100,7 @@ public final class AnalysisToolPak implements UDFFinder {
         r(m, "DOLLARDE", null);
         r(m, "DOLLARFR", null);
         r(m, "DURATION", null);
-        r(m, "EDATE", null);
+        r(m, "EDATE", EDate.instance);
         r(m, "EFFECT", null);
         r(m, "EOMONTH", null);
         r(m, "ERF", null);
diff --git a/src/java/org/apache/poi/ss/formula/functions/EDate.java b/src/java/org/apache/poi/ss/formula/functions/EDate.java
new file mode 100644 (file)
index 0000000..fbc08c0
--- /dev/null
@@ -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);
+    }
+}
diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java b/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java
new file mode 100644 (file)
index 0000000..cf19438
--- /dev/null
@@ -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());
+    }
+}