diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java index 54a368fb1..34dcc7cda 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java +++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java @@ -14,12 +14,101 @@ * 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; + } }