]> source.dussan.org Git - poi.git/commitdiff
Fixes for DAY/MONTH/YEAR functions (junit cases added)
authorJosh Micich <josh@apache.org>
Mon, 8 Sep 2008 20:28:05 +0000 (20:28 +0000)
committerJosh Micich <josh@apache.org>
Mon, 8 Sep 2008 20:28:05 +0000 (20:28 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@693250 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Day.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Month.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Year.java [deleted file]
src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls

index fe58c69c095013fee76cecc18b9fa4c9b4c932ca..ff714160254eebdbbbc6ef5b6bbdc2b605498113 100644 (file)
@@ -143,9 +143,9 @@ public abstract class FunctionEval implements OperationEval {
         retval[64] = new Match(); // MATCH
         retval[65] = new Date(); // DATE
         retval[66] = new Time(); // TIME
-        retval[67] = new Day(); // DAY
-        retval[68] = new Month(); // MONTH
-        retval[69] = new Year(); // YEAR
+        retval[67] = CalendarFieldFunction.DAY; // DAY
+        retval[68] = CalendarFieldFunction.MONTH; // MONTH
+        retval[69] = CalendarFieldFunction.YEAR; // YEAR
         retval[70] = new Weekday(); // WEEKDAY
         retval[71] = new Hour(); // HOUR
         retval[72] = new Minute(); // MINUTE
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java
new file mode 100644 (file)
index 0000000..3df7c9c
--- /dev/null
@@ -0,0 +1,98 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+
+/**
+ * Implementation of Excel functions DAY, MONTH and YEAR
+ * 
+ * 
+ * @author Guenter Kickinger g.kickinger@gmx.net
+ */
+public final class CalendarFieldFunction implements Function {
+       
+       public static final Function YEAR = new CalendarFieldFunction(Calendar.YEAR, false);
+       public static final Function MONTH = new CalendarFieldFunction(Calendar.MONTH, true);
+       public static final Function DAY = new CalendarFieldFunction(Calendar.DAY_OF_MONTH, false);
+       
+       private final int _dateFieldId;
+       private final boolean _needsOneBaseAdjustment;
+
+       private CalendarFieldFunction(int dateFieldId, boolean needsOneBaseAdjustment) {
+               _dateFieldId = dateFieldId;
+               _needsOneBaseAdjustment = needsOneBaseAdjustment;
+       }
+
+       public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+               if (operands.length != 1) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+
+               int val;
+               try {
+                       ValueEval ve = OperandResolver.getSingleValue(operands[0], srcCellRow, srcCellCol);
+
+                       if (ve == BlankEval.INSTANCE) {
+                               val = 0;
+                       } else {
+                               val = OperandResolver.coerceValueToInt(ve);
+                       }
+               } catch (EvaluationException e) {
+                       return e.getErrorEval();
+               }
+               if (val < 0) {
+                       return ErrorEval.NUM_ERROR;
+               }
+               return new NumberEval(getCalField(val));
+       }
+
+       private int getCalField(int serialDay) {
+               if (serialDay == 0) {
+                       // Special weird case
+                       // day zero should be 31-Dec-1899,  but Excel seems to think it is 0-Jan-1900
+                       switch (_dateFieldId) {
+                               case Calendar.YEAR: return 1900;
+                               case Calendar.MONTH: return 1;
+                               case Calendar.DAY_OF_MONTH: return 0;
+                       }
+                       throw new IllegalStateException("bad date field " + _dateFieldId);
+               }
+               Date d = HSSFDateUtil.getJavaDate(serialDay, false); // TODO fix 1900/1904 problem
+
+               Calendar c = new GregorianCalendar();
+               c.setTime(d);
+
+               int result = c.get(_dateFieldId);
+               if (_needsOneBaseAdjustment) {
+                       result++;
+               }
+               return result;
+       }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Day.java b/src/java/org/apache/poi/hssf/record/formula/functions/Day.java
deleted file mode 100644 (file)
index 0ae5694..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.usermodel.HSSFDateUtil;
-
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-
-/**
- * @author Pavel Krupets
- */
-public class Day extends NumericFunction {
-    /**
-     * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
-     */
-    public Eval evaluate(Eval[] operands, int srcCellRow, short
-srcCellCol) {
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0],
-srcCellRow, srcCellCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
-                    java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
-                    java.util.Calendar c = java.util.Calendar.getInstance();
-                    c.setTime(d);
-                    retval = new NumberEval(c.get(java.util.Calendar.DAY_OF_MONTH));
-                } else {
-                    retval = ErrorEval.NUM_ERROR;
-                }
-            } else if (ve instanceof BlankEval) {
-                // do nothing
-            } else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        return retval;
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Month.java b/src/java/org/apache/poi/hssf/record/formula/functions/Month.java
deleted file mode 100644 (file)
index d5178b2..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFDateUtil;
-
-/**
- * 
- * @author Guenter Kickinger g.kickinger@gmx.net
- *
- */
-public class Month extends NumericFunction {
-
-       /* (non-Javadoc)
-        * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
-        */
-       public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
-                    java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
-                    retval = new NumberEval(d.getMonth()+1);
-                } else {
-                    retval = ErrorEval.NUM_ERROR;
-                }
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            } else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        return retval;
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Year.java b/src/java/org/apache/poi/hssf/record/formula/functions/Year.java
deleted file mode 100644 (file)
index b461a09..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFDateUtil;
-
-/**
- * 
- * @author Guenter Kickinger g.kickinger@gmx.net
- *
- */
-
-public class Year extends NumericFunction {
-
-       /* (non-Javadoc)
-        * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
-        */
-       public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
-                    java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
-                    retval = new NumberEval(d.getYear()+1900);
-                } else {
-                    retval = ErrorEval.NUM_ERROR;
-                }
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            } else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        return retval;
-    }
-}
\ No newline at end of file
index 99cb61a58811b2246af6cc66651997d897dffe0c..68a12d834fed0d5ed7268b383a765729e8c9fa0e 100644 (file)
Binary files a/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls and b/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls differ