From: Josh Micich Date: Mon, 8 Sep 2008 20:28:05 +0000 (+0000) Subject: Fixes for DAY/MONTH/YEAR functions (junit cases added) X-Git-Tag: REL_3_2_FINAL~81 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=49ddf85f9b4be3e217be24c7895931c5cd5ae311;p=poi.git 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 --- 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 fe58c69c09..ff71416025 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 0000000000..3df7c9c5d5 --- /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 0ae5694767..0000000000 --- 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 d5178b22df..0000000000 --- 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 b461a09668..0000000000 --- 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 99cb61a588..68a12d834f 100644 Binary files a/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls and b/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls differ