/* ==================================================================== | |
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.ss.formula.functions; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertTrue; | |
import java.util.Calendar; | |
import java.util.Date; | |
import org.apache.poi.ss.formula.OperationEvaluationContext; | |
import org.apache.poi.ss.formula.eval.BlankEval; | |
import org.apache.poi.ss.formula.eval.ErrorEval; | |
import org.apache.poi.ss.formula.eval.NumberEval; | |
import org.apache.poi.ss.formula.eval.StringEval; | |
import org.apache.poi.ss.formula.eval.ValueEval; | |
import org.apache.poi.ss.usermodel.DateUtil; | |
import org.apache.poi.ss.usermodel.FormulaError; | |
import org.apache.poi.util.LocaleUtil; | |
import org.junit.Test; | |
public class TestEOMonth { | |
private static final double BAD_DATE = -1.0; | |
private static final double DATE_1900_01_01 = 1.0; | |
private static final double DATE_1900_01_31 = 31.0; | |
private static final double DATE_1900_02_28 = 59.0; | |
private static final double DATE_1902_09_26 = 1000.0; | |
private static final double DATE_1902_09_30 = 1004.0; | |
private static final double DATE_2034_06_09 = 49104.0; | |
private static final double DATE_2034_06_30 = 49125.0; | |
private static final double DATE_2034_07_31 = 49156.0; | |
private final FreeRefFunction eOMonth = EOMonth.instance; | |
private final OperationEvaluationContext ec = new OperationEvaluationContext(null, null, 0, 0, 0, null); | |
@Test | |
public void testEOMonthProperValues() { | |
// verify some border-case combinations of startDate and month-increase | |
checkValue(DATE_1900_01_01, 0, DATE_1900_01_31); | |
checkValue(DATE_1900_01_01, 1, DATE_1900_02_28); | |
checkValue(DATE_1902_09_26, 0, DATE_1902_09_30); | |
checkValue(DATE_2034_06_09, 0, DATE_2034_06_30); | |
checkValue(DATE_2034_06_09, 1, DATE_2034_07_31); | |
} | |
@Test | |
public void testEOMonthBadDateValues() { | |
checkValue(0.0, -2, BAD_DATE); | |
checkValue(0.0, -3, BAD_DATE); | |
checkValue(DATE_1900_01_31, -1, BAD_DATE); | |
} | |
private void checkValue(double startDate, int monthInc, double expectedResult) { | |
ValueEval ve[] = {new NumberEval(startDate), new NumberEval(monthInc)}; | |
NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); | |
assertEquals(expectedResult, result.getNumberValue(), 0); | |
} | |
@Test | |
public void testEOMonthZeroDate() { | |
NumberEval result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(0), new NumberEval(0)}, ec); | |
assertEquals("0 startDate is 1900-01-00", DATE_1900_01_31, result.getNumberValue(), 0); | |
result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(0), new NumberEval(1)}, ec); | |
assertEquals("0 startDate is 1900-01-00", DATE_1900_02_28, result.getNumberValue(), 0); | |
} | |
@Test | |
public void testEOMonthInvalidArguments() { | |
ValueEval result = eOMonth.evaluate(new ValueEval[] {new NumberEval(DATE_1902_09_26)}, ec); | |
assertTrue(result instanceof ErrorEval); | |
assertEquals(FormulaError.VALUE.getCode(), ((ErrorEval) result).getErrorCode(), 0); | |
result = eOMonth.evaluate(new ValueEval[] {new StringEval("a"), new StringEval("b")}, ec); | |
assertTrue(result instanceof ErrorEval); | |
assertEquals(FormulaError.VALUE.getCode(), ((ErrorEval) result).getErrorCode(), 0); | |
} | |
@Test | |
public void checkOffset() { | |
for (int offset=-12; offset<=12; offset++) { | |
Calendar cal = LocaleUtil.getLocaleCalendar(); | |
Date startDate = cal.getTime(); | |
cal.add(Calendar.MONTH, offset); | |
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); | |
cal.clear(Calendar.HOUR); | |
cal.set(Calendar.HOUR_OF_DAY, 0); | |
cal.clear(Calendar.MINUTE); | |
cal.clear(Calendar.SECOND); | |
cal.clear(Calendar.MILLISECOND); | |
Date expDate = cal.getTime(); | |
ValueEval ve[] = { | |
new NumberEval(DateUtil.getExcelDate(startDate)), | |
new NumberEval(offset) | |
}; | |
NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); | |
Date actDate = DateUtil.getJavaDate(result.getNumberValue()); | |
assertEquals(expDate, actDate); | |
} | |
} | |
@Test | |
public void testBug56688() { | |
ValueEval ve[] = {new NumberEval(DATE_1902_09_26), new RefEvalImplementation(new NumberEval(0))}; | |
NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); | |
assertEquals(DATE_1902_09_30, result.getNumberValue(), 0); | |
} | |
@Test | |
public void testRefEvalStartDate() { | |
ValueEval ve[] = {new RefEvalImplementation(new NumberEval(DATE_1902_09_26)), new NumberEval(0)}; | |
NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); | |
assertEquals(DATE_1902_09_30, result.getNumberValue(), 0); | |
} | |
@Test | |
public void testEOMonthBlankValueEval() { | |
NumberEval evaluate = (NumberEval) eOMonth.evaluate(new ValueEval[] {BlankEval.instance, new NumberEval(0)}, ec); | |
assertEquals("Blank is handled as 0", DATE_1900_01_31, evaluate.getNumberValue(), 0); | |
} | |
@Test | |
public void testEOMonthBlankRefValueEval() { | |
ValueEval[] ve1 = {new RefEvalImplementation(BlankEval.instance), new NumberEval(1)}; | |
NumberEval result = (NumberEval) eOMonth.evaluate(ve1, ec); | |
assertEquals("Blank is handled as 0", DATE_1900_02_28, result.getNumberValue(), 0); | |
ValueEval[] ve2 = {new NumberEval(1), new RefEvalImplementation(BlankEval.instance)}; | |
result = (NumberEval) eOMonth.evaluate(ve2, ec); | |
assertEquals("Blank is handled as 0", DATE_1900_01_31, result.getNumberValue(), 0); | |
} | |
} |