2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package org
.apache
.poi
.hssf
.record
.formula
.functions
;
19 import java
.util
.Calendar
;
20 import java
.util
.GregorianCalendar
;
22 import org
.apache
.poi
.hssf
.usermodel
.HSSFDateUtil
;
24 import org
.apache
.poi
.hssf
.record
.formula
.eval
.Eval
;
25 import org
.apache
.poi
.hssf
.record
.formula
.eval
.RefEval
;
26 import org
.apache
.poi
.hssf
.record
.formula
.eval
.BlankEval
;
27 import org
.apache
.poi
.hssf
.record
.formula
.eval
.ErrorEval
;
28 import org
.apache
.poi
.hssf
.record
.formula
.eval
.ValueEval
;
29 import org
.apache
.poi
.hssf
.record
.formula
.eval
.NumberEval
;
30 import org
.apache
.poi
.hssf
.record
.formula
.eval
.NumericValueEval
;
33 * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
35 public class Date
extends NumericFunction
{
37 * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
39 public Eval
evaluate(Eval
[] operands
, int srcCellRow
, short srcCellCol
) {
40 if (operands
.length
== 3) {
41 ValueEval ve
[] = new ValueEval
[3];
43 ve
[0] = singleOperandEvaluate(operands
[0], srcCellRow
, srcCellCol
);
44 ve
[1] = singleOperandEvaluate(operands
[1], srcCellRow
, srcCellCol
);
45 ve
[2] = singleOperandEvaluate(operands
[2], srcCellRow
, srcCellCol
);
47 if (validValues(ve
)) {
48 int year
= getYear(ve
[0]);
49 int month
= (int) ((NumericValueEval
) ve
[1]).getNumberValue() - 1;
50 int day
= (int) ((NumericValueEval
) ve
[2]).getNumberValue();
52 if (year
< 0 || month
< 0 || day
< 0) {
53 return ErrorEval
.VALUE_INVALID
;
56 if (year
== 1900 && month
== Calendar
.FEBRUARY
&& day
== 29) {
57 return new NumberEval(60.0);
61 if ((month
== Calendar
.JANUARY
&& day
>= 60) ||
62 (month
== Calendar
.FEBRUARY
&& day
>= 30))
68 Calendar c
= new GregorianCalendar();
70 c
.set(year
, month
, day
, 0, 0, 0);
71 c
.set(Calendar
.MILLISECOND
, 0);
73 return new NumberEval(HSSFDateUtil
.getExcelDate(c
.getTime(), false)); // XXX fix 1900/1904 problem
77 return ErrorEval
.VALUE_INVALID
;
80 private int getYear(ValueEval ve
) {
81 int year
= (int) ((NumericValueEval
) ve
).getNumberValue();
87 return year
< 1900 ?
1900 + year
: year
;
90 private boolean validValues(ValueEval
[] values
) {
91 for (int i
= 0; i
< values
.length
; i
++) {
92 ValueEval value
= values
[i
];
94 if (value
instanceof RefEval
) {
95 RefEval re
= (RefEval
) value
;
96 ValueEval ive
= re
.getInnerValueEval();
98 if (ive
instanceof BlankEval
) {
99 value
= new NumberEval(0);
100 } else if (ive
instanceof NumericValueEval
) {
107 if (!(value
instanceof NumericValueEval
)) {