From f722d1e20990d65ddeb99f4aaa8b705351775871 Mon Sep 17 00:00:00 2001
From: Josh Micich <josh@apache.org>
Date: Mon, 8 Sep 2008 20:28:05 +0000
Subject: [PATCH] Fixes for DAY/MONTH/YEAR functions (junit cases added)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@693250 13f79535-47bb-0310-9956-ffa450edef68
---
 .../record/formula/eval/FunctionEval.java     |   6 +-
 .../functions/CalendarFieldFunction.java      |  98 ++++++++++++++++++
 .../hssf/record/formula/functions/Day.java    |  64 ------------
 .../hssf/record/formula/functions/Month.java  |  67 ------------
 .../hssf/record/formula/functions/Year.java   |  68 ------------
 .../poi/hssf/data/FormulaEvalTestData.xls     | Bin 153600 -> 154624 bytes
 6 files changed, 101 insertions(+), 202 deletions(-)
 create mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java
 delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Day.java
 delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Month.java
 delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Year.java

diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
index fe58c69c0..ff7141602 100644
--- a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
+++ b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
@@ -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
index 000000000..3df7c9c5d
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java
@@ -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
index 0ae569476..000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Day.java
+++ /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
index d5178b22d..000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Month.java
+++ /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
index b461a0966..000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Year.java
+++ /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
diff --git a/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls b/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls
index 99cb61a58811b2246af6cc66651997d897dffe0c..68a12d834fed0d5ed7268b383a765729e8c9fa0e 100644
GIT binary patch
delta 5088
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

delta 4019
zcmZvf3s{t87RS%|zIR||fMH0KtB8nl5fxGd6q1{_l>}GJTPs+mK$#?@X(pK4s)-2>
z`C)6VX05PWq>U?@B2;GdXbDQ`u7IY<T3DgEnVQi5WoFiPAK^Lt{+#c;=e_-z@1gjB
zp?Hs>G@gxR310k@<{qGo-J74!TNJ?tt4>*@7`poSZTr~t8M|1X6>F6{2Fq=cXEN`q
ztdL3DL(5X#QWGV<-<t|#J?gF3bzKUtw0v#!w%pMh?5e-PrutbD3@*L7ewHkUa#hHS
zN|}fh>K$nGxc6(5!P6AMOtExWu~#%12HIN~jJ9UpmSIN6ROt?7jKA0AYhyoGrg6XR
z;c3eG-?nu|TU-3JsxB9WHPBpa^j@X+q*Z#%{NJy9DhP>r)N;i)SVRtwjI@~jl5Apz
zL%ik?=N%&0-(HjJ5Y-OxqeH~@x7WPj5Fa^&bAbI(nnRR1#8(dCH^5$#?GSG}#J3JH
zBG6t_=nw}TqT3--2HI=ZJH+P$%WNBbEXXcy1`V@iLI>H47dyoJ4sp{V;)CtQi-YaM
zmBIE=6CI*t@N>3?pAYo51P)nY`{nf^_K{x<nbDiEhJ?8E>EH2;ybE_4zwC*nD++UR
zpI(&tL_uM}OK?%tWlQ=PAHT-`NH@9B^uqat1!=jD*`K@871g?SOi5gkb2O1FO4fs$
zK;38}BgSapc2L9+8Q`~#V5#(7ENWDu)!<t21F#Nsk0bIFM3cd(U>$fA3>iZdp(A=7
zd=vB?OEkcVXbY%0Q4u-EV*$=Y#o$ZeEwCHRNg!GbyPX3sfR8*xG}l0M3_K2|jU$?7
zB-#%i0^<^i9&#c22lxRPmP9lhJF5b#LEmId>_+q&_!rPGg(%QeL{tv3%|xW866xKE
zR)R&~_u!A<g7HMTW}>rTE0{ikDAR+e3H%C7n}~%xK=dJa3>-0uXjC7f_rQH%#AKo<
zPoj6gy<o`ikn2nI2DqyT!gC6dPd^+nSPFK7su$4<X+$rAJ)rO=TJ|u}^Wb&xCivu3
zqI@5sPOuAnG@WR^FVQLR3^+LhSK)^f0uO;hrx8W^V<F&PaM16u(a`=l0f=p&^K@KA
z0MRON4fqSl18@zQL`%VT@EdT!3?ginTEIFm`w^lPc;zzK0A|m`@9;_&cp5C6MKlv0
zxdXO=%V!hKfj54bjr%_ZkvE6vVVL6^@B}z_F76U0X$9-S%twi0;ECg4H8|xDxLbJQ
zAh;b&o<}qoo;V0@2Zv@6nc#`{z%5`%HcSmq>;Tt-Uh|1=gXQy!uo{>{{}_%D+yFiW
zbI{{Nm%!)2dGN+9umyZ-0q!53=mft2AAf>q0zA<I)`4>t5+%SBr@{ST#v-DT@Wdxz
zB^aGU<PA@}18xSxC*|U=6Q<Y-t^h?I(Z9i$z#MqP|4H0G_*ZZPyb<*j`~pw>4cr8V
zFUELyVUwkC`P)T5EyteAu%+EZeGkE!ALC3<5-mIn@3+Fj?XcZ<M6Yz=5BNu%$8GuP
z!PKKL?Za!K^#P_&yqKDNnLg~#G<zV^nqa19LYP(!W4b+(DL0Af;AEx=)0sG%X;B{2
zg2hb!`J71n9FyDgOdV^O=B#5{_%f5IU^4%iDfn#+s>Xl=OuJx{Z%$&Oukfsusr@``
zbCI<Y4`qoq=^95^Pp-J37dH-iI$1w`F+qqfsr2g#R5dfJ%DVdH5iG7EW!bwiNYoE%
z(OJ%H{8G)ys<OOS5+%rev#_+6REsOJWb39k)k$Hsma(tw7J<Pi?Re!+qU**woh5(s
zXtfw)sy4qW=w~F7OSih13HL&IluD`ATcyQ{nt`#aEFr>QcHM0mD`KVSu%xJoZ<Jai
z%Jo9I=4}~W5y~^ISrsV;?zZmQ8SX9G<>XBV{nc4vwbrhKX4fqZYu-QB%n>)y|87rD
z&(Gj31TKN@AbvsIMRX&25V#n!u4(vtkb)Hq?;N3)W3Abpqtrd`PO@m7i6XRksm^k)
zbF7-Zv&`aib+pJd7wW9juZFs4nL0LGH{RUGMJnmhM|N{3y<(<RyzBozH}O8XN%zT3
zxlb<bKDqRJIqQ*IVQjifMoMFa5~-hxO`W)7Vs6kfzGWZnhjMnZ-u|V{AQJDa(`hYE
z9HHKXaB=3L;)GOVq<TxLT&W^)hgyX*XNU@!yDD=fQu*n5geZopnX2cPhpJ>M)6R|L
zW(C|kiZ6-_xRDwyn&W*$3#4{tDu;>;*-lO8(Q0K@l@_1Qv1(3Ot+qU!N2&P`)#?18
z`W(cibe<v3$`<h%eBDj0M|spdjBAF-lcE?^yXJA2NR!KHl&ULqgHF3E72&e9@GOoN
z#keKy@hpBpEuUGXUCKiL%9&L)-r4M}SJ$J*$Q*2h!Z327RLyd&+j2NUG|JgO%i)!-
zy(jvXDo^w^g{UTb882bOmyi+cPo|o)%lUYKI3Y*w-ilr3%Uzz{ibd9APFD@PEX7O{
zHSDqiVzq`<?0~Rp*kyy9$F+jp2C2n6%QXK(JVq_nm1(mN@ib8^TU8(8WujE7(8HV{
z5~tM(E%z`l6x-$IP9Nr}VuyS>xRxh~12VUymeYi{+*DmHr--9+X--G5pg^ZGZQK!_
zsa9h8ZAUm>mE~uT;DYOAQA8b&Q1^t@*37Hpp&sI}%x!99e{n#ncN;lC?33!GRFQIm
zYmGSXJu(;2gxot)B|@nc*v$MUj#3X`s#lw2m0aXUO*q?1S#`aMgTz}>d7pyX0af$R
zDPC<9+hwx81x=c9fM2)paP<nr1Fcw`2iBX~iUYi`WV5!Sm7~=?m}qY+M~MnKtfQ5O
zs5Gleb8q9}qFknu+K{TpD)QQ}ih8*UtqsoiMAfl2d(WTS(4kb84?EAPq6Dhu+4Jlz
zROzMCOFUjQ%8~!Pgt`k-nc6Y50c{i8IYe!g{oB!hfjkvWs$!{*wsUxIi)-yTf4Tbb
z%Q%!!%suZikL=BqU*<Jpy`0gfgFjGM)HGk=-K>dbHuF)9o4F5vYD0q!$89)a!$}(&
zwX%Pq^0W=jHk{GQE^;4jdMAI;>*Ge9^fBIIq$PdF@yR#vfz?2;F@@u&45?*&#KB}H
zUwnWWbk0;M+$cb5Cl_+=VX~l)!DOaqNUQq}{><2LN~gtr&kOZZCB9jp({_K)-KrqH
zR`~;mjq@cR{HN6)??8Mi$uHX{CH1D*h>2v%h;LtCS)~lc8f0oHzD*|0+{H&+rgShZ
z#*%N{xcB~w+IpP>hjrsa-UBW1CMCRG$qivbxFgI6yln|@TIz%F)E>UhUgP~B2P6Cu
z0SMV*02qiEhzLRqLg1xLLl9vIyqqZ%5sr}c-FxTHWNpPYUbp`SFLrn8_=%}f(KdQ0
z`SRVmvF2%^c)2-s3x%Q#HAn|2;*Zj0@AgsViu!Ok#MM&?RWrhCwHQyOK%9`NYELCx
zorTmnPi4NE4Kc2-vQxC<SxtLi<yGGAt(+S>B{D8DIVvt{LR9K+BgoB|nvt9kG%9vf
zQgm!|a&(+6ke`^65EL5|8yy#ulr%mrb@YRAsWCEAN7oF=ROTvr`#;sHW!lP^n)*kS
GMBT4usuRQj