]> source.dussan.org Git - poi.git/commitdiff
Implement the date function, patch from Pavel
authorNick Burch <nick@apache.org>
Tue, 25 Sep 2007 13:36:36 +0000 (13:36 +0000)
committerNick Burch <nick@apache.org>
Tue, 25 Sep 2007 13:36:36 +0000 (13:36 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@579243 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java

index 54a368fb11d08ac379f5e415c3456f601c725340..34dcc7cdae4421966d50946fb53f043df5624f1e 100644 (file)
 * 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;
 
-public class Date extends NotImplementedFunction {
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
 
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.RefEval;
+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.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+
+/**
+ * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
+ */
+public class Date 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) {
+        if (operands.length == 3) {
+            ValueEval ve[] = new ValueEval[3];
+            
+            ve[0] = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+            ve[1] = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol);
+            ve[2] = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol);
+            
+            if (validValues(ve)) {
+                int year = getYear(ve[0]);
+                int month = (int) ((NumericValueEval) ve[1]).getNumberValue() - 1;
+                int day = (int) ((NumericValueEval) ve[2]).getNumberValue();
+                
+                if (year < 0 || month < 0 || day < 0) {
+                    return ErrorEval.VALUE_INVALID;
+                }
+                
+                if (year == 1900 && month == Calendar.FEBRUARY && day == 29) {
+                    return new NumberEval(60.0);
+                }
+                
+                if (year == 1900) {
+                    if ((month == Calendar.JANUARY && day >= 60) ||
+                        (month == Calendar.FEBRUARY && day >= 30))
+                    {
+                        day--;
+                    }
+                }
+                
+                Calendar c = new GregorianCalendar();
+                
+                c.set(year, month, day, 0, 0, 0);
+                c.set(Calendar.MILLISECOND, 0);
+                
+                return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime()));
+            }
+        }
+        
+        return ErrorEval.VALUE_INVALID;
+    }
+    
+    private int getYear(ValueEval ve) {
+        int year = (int) ((NumericValueEval) ve).getNumberValue();
+        
+        if (year < 0) {
+            return -1;
+        }
+        
+        return year < 1900 ? 1900 + year : year;
+    }
+    
+    private boolean validValues(ValueEval[] values) {
+        for (int i = 0; i < values.length; i++) {
+            ValueEval value =  values[i];
+            
+            if (value instanceof RefEval) {
+                RefEval re = (RefEval) value;
+                ValueEval ive = re.getInnerValueEval();
+                
+                if (ive instanceof BlankEval) {
+                    value = new NumberEval(0);
+                } else if (ive instanceof NumericValueEval) {
+                    value = ive;
+                } else {
+                    return false;
+                }
+            }
+            
+            if (!(value instanceof NumericValueEval)) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
 }