166 lines
6.3 KiB
Java
166 lines
6.3 KiB
Java
/* ====================================================================
|
|
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 java.util.Locale;
|
|
|
|
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
|
|
import org.apache.poi.ss.formula.eval.BoolEval;
|
|
import org.apache.poi.ss.formula.eval.NumberEval;
|
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
|
import org.apache.poi.util.LocaleUtil;
|
|
import org.junit.Test;
|
|
|
|
public final class TestDays360 {
|
|
|
|
/**
|
|
* @param month 1-based
|
|
*/
|
|
private static Date makeDate(int year, int month, int day) {
|
|
Calendar cal = LocaleUtil.getLocaleCalendar(year, month-1, day);
|
|
return cal.getTime();
|
|
}
|
|
|
|
private static Date decrementDay(Date d) {
|
|
Calendar c = LocaleUtil.getLocaleCalendar();
|
|
c.setTime(d);
|
|
c.add(Calendar.DAY_OF_MONTH, -1);
|
|
return c.getTime();
|
|
}
|
|
|
|
@Test
|
|
public void testBasic() {
|
|
confirm(120, 2009, 1, 15, 2009, 5, 15);
|
|
confirm(158, 2009, 1, 26, 2009, 7, 4);
|
|
|
|
// same results in leap years
|
|
confirm(120, 2008, 1, 15, 2008, 5, 15);
|
|
confirm(158, 2008, 1, 26, 2008, 7, 4);
|
|
|
|
// longer time spans
|
|
confirm(562, 2008, 8, 11, 2010, 3, 3);
|
|
confirm(916, 2007, 2, 23, 2009, 9, 9);
|
|
|
|
// other tests
|
|
confirm(1, makeDate(1993, 2, 28), makeDate(1993, 3, 1), false);
|
|
confirm(1, makeDate(1996, 2, 29), makeDate(1996, 3, 1), false);
|
|
confirm(-2, makeDate(1993, 2, 28), makeDate(1993, 2, 28), false);
|
|
confirm(3, makeDate(1993, 2, 28), makeDate(1993, 3, 1), true);
|
|
confirm(2, makeDate(1996, 2, 29), makeDate(1996, 3, 1), true);
|
|
|
|
// from https://support.office.com/en-us/article/DAYS360-function-B9A509FD-49EF-407E-94DF-0CBDA5718C2A
|
|
confirm(1, makeDate(2011, 1, 30), makeDate(2011, 2, 1), false);
|
|
confirm(360, makeDate(2011, 1, 1), makeDate(2011, 12, 31), false);
|
|
confirm(30, makeDate(2011, 1, 1), makeDate(2011, 2, 1), false);
|
|
}
|
|
|
|
private static void confirm(int expResult, int y1, int m1, int d1, int y2, int m2, int d2) {
|
|
confirm(expResult, makeDate(y1, m1, d1), makeDate(y2, m2, d2), false);
|
|
confirm(-expResult, makeDate(y2, m2, d2), makeDate(y1, m1, d1), false);
|
|
}
|
|
|
|
/**
|
|
* The <tt>method</tt> parameter only makes a difference when the second parameter
|
|
* is the last day of the month that does <em>not</em> have 30 days.
|
|
*/
|
|
@Test
|
|
public void testMonthBoundaries() {
|
|
// jan
|
|
confirmMonthBoundary(false, 2001, 1, 0, 0, 2, 3, 4);
|
|
confirmMonthBoundary(true, 2001, 1, 0, 0, 1, 2, 3);
|
|
// feb
|
|
confirmMonthBoundary(false, 2001, 2,-2, 1, 2, 3, 4);
|
|
confirmMonthBoundary(true, 2001, 2, 0, 1, 2, 3, 4);
|
|
// mar
|
|
confirmMonthBoundary(false, 2001, 3, 0, 0, 2, 3, 4);
|
|
confirmMonthBoundary(true, 2001, 3, 0, 0, 1, 2, 3);
|
|
// apr
|
|
confirmMonthBoundary(false, 2001, 4, 0, 1, 2, 3, 4);
|
|
confirmMonthBoundary(true, 2001, 4, 0, 1, 2, 3, 4);
|
|
// may
|
|
confirmMonthBoundary(false, 2001, 5, 0, 0, 2, 3, 4);
|
|
confirmMonthBoundary(true, 2001, 5, 0, 0, 1, 2, 3);
|
|
// jun
|
|
confirmMonthBoundary(false, 2001, 6, 0, 1, 2, 3, 4);
|
|
confirmMonthBoundary(true, 2001, 6, 0, 1, 2, 3, 4);
|
|
// leap year
|
|
confirmMonthBoundary(false, 2012, 2, -1, 1, 2, 3, 4);
|
|
confirmMonthBoundary(true, 2012, 2, 0, 1, 2, 3, 4);
|
|
|
|
// bug 60029
|
|
Date start = makeDate(2018, 2, 28);
|
|
Date end = makeDate(2018, 3, 31);
|
|
confirm(30, start, end, false);
|
|
|
|
// examples from https://support.office.com/en-us/article/DAYS360-function-B9A509FD-49EF-407E-94DF-0CBDA5718C2A
|
|
start = makeDate(2011, 1, 30);
|
|
end = makeDate(2011, 2, 1);
|
|
confirm(1, start, end, false);
|
|
|
|
start = makeDate(2011, 1, 1);
|
|
end = makeDate(2011, 12, 31);
|
|
confirm(360, start, end, false);
|
|
|
|
start = makeDate(2011, 1, 1);
|
|
end = makeDate(2011, 2, 1);
|
|
confirm(30, start, end, false);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param monthNo 1-based
|
|
*/
|
|
private static void confirmMonthBoundary(boolean method, int year, int monthNo, int...diffs) {
|
|
Date firstDayOfNextMonth = makeDate(year, monthNo+1, 1);
|
|
Date secondArg = decrementDay(firstDayOfNextMonth);
|
|
Date firstArg = secondArg;
|
|
|
|
for (int expResult : diffs) {
|
|
confirm(expResult, firstArg, secondArg, method);
|
|
firstArg = decrementDay(firstArg);
|
|
}
|
|
|
|
}
|
|
private static void confirm(int expResult, Date firstArg, Date secondArg, boolean method) {
|
|
ValueEval ve;
|
|
if (method) {
|
|
ve = invokeDays360(convert(firstArg), convert(secondArg), BoolEval.TRUE);
|
|
} else {
|
|
ve = invokeDays360(convert(firstArg), convert(secondArg));
|
|
}
|
|
assertTrue("wrong return type (" + ve.getClass().getName() + ")", ve instanceof NumberEval);
|
|
|
|
NumberEval numberEval = (NumberEval) ve;
|
|
String err = String.format(Locale.ROOT, "days360(%tF,%tF,%b) wrong result", firstArg, secondArg, method);
|
|
assertEquals(err, expResult, numberEval.getNumberValue(), 0);
|
|
}
|
|
|
|
private static ValueEval invokeDays360(ValueEval...args) {
|
|
return new Days360().evaluate(args, -1, -1);
|
|
}
|
|
|
|
private static NumberEval convert(Date d) {
|
|
return new NumberEval(HSSFDateUtil.getExcelDate(d));
|
|
}
|
|
}
|