Bug 60029: apply suggested fix and fix some IntelliJ warnings

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1765018 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2016-10-15 06:54:20 +00:00
parent b51eb49e58
commit 37116e84e5
2 changed files with 130 additions and 118 deletions

View File

@ -67,38 +67,33 @@ import org.apache.poi.util.LocaleUtil;
*/
public class Days360 extends Var2or3ArgFunction {
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
double result;
try {
double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
result = evaluate(d0, d1, false);
return new NumberEval(evaluate(d0, d1, false));
} catch (EvaluationException e) {
return e.getErrorEval();
}
return new NumberEval(result);
}
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
ValueEval arg2) {
double result;
try {
double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
ValueEval ve = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex);
Boolean method = OperandResolver.coerceValueToBoolean(ve, false);
result = evaluate(d0, d1, method == null ? false : method.booleanValue());
return new NumberEval(evaluate(d0, d1, method != null && method.booleanValue()));
} catch (EvaluationException e) {
return e.getErrorEval();
}
return new NumberEval(result);
}
private static double evaluate(double d0, double d1, boolean method) {
Calendar realStart = getDate(d0);
Calendar realEnd = getDate(d1);
int startingDate[] = getStartingDate(realStart, method);
int endingDate[] = getEndingDate(realEnd, realStart, method);
int endingDate[] = getEndingDate(realEnd, startingDate, method);
return
(endingDate[0]*360+endingDate[1]*30+endingDate[2])-
(startingDate[0]*360+startingDate[1]*30+startingDate[2]);
@ -111,28 +106,26 @@ public class Days360 extends Var2or3ArgFunction {
}
private static int[] getStartingDate(Calendar realStart, boolean method) {
Calendar d = realStart;
int yyyy = d.get(Calendar.YEAR);
int mm = d.get(Calendar.MONTH);
int dd = Math.min(30, d.get(Calendar.DAY_OF_MONTH));
int yyyy = realStart.get(Calendar.YEAR);
int mm = realStart.get(Calendar.MONTH);
int dd = Math.min(30, realStart.get(Calendar.DAY_OF_MONTH));
if (method == false && isLastDayOfMonth(d)) dd = 30;
if (!method && isLastDayOfMonth(realStart)) dd = 30;
return new int[]{yyyy,mm,dd};
}
private static int[] getEndingDate(Calendar realEnd, Calendar realStart, boolean method) {
Calendar d = realEnd;
int yyyy = d.get(Calendar.YEAR);
int mm = d.get(Calendar.MONTH);
int dd = Math.min(30, d.get(Calendar.DAY_OF_MONTH));
private static int[] getEndingDate(Calendar realEnd, int startingDate[], boolean method) {
int yyyy = realEnd.get(Calendar.YEAR);
int mm = realEnd.get(Calendar.MONTH);
int dd = Math.min(30, realEnd.get(Calendar.DAY_OF_MONTH));
if (method == false && realEnd.get(Calendar.DAY_OF_MONTH) == 31) {
if (realStart.get(Calendar.DAY_OF_MONTH) < 30) {
d.set(Calendar.DAY_OF_MONTH, 1);
d.add(Calendar.MONTH, 1);
yyyy = d.get(Calendar.YEAR);
mm = d.get(Calendar.MONTH);
if (!method && realEnd.get(Calendar.DAY_OF_MONTH) == 31) {
if (startingDate[2] < 30) {
realEnd.set(Calendar.DAY_OF_MONTH, 1);
realEnd.add(Calendar.MONTH, 1);
yyyy = realEnd.get(Calendar.YEAR);
mm = realEnd.get(Calendar.MONTH);
dd = 1;
} else {
dd = 30;

View File

@ -67,6 +67,11 @@ public final class TestDays360 {
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) {
@ -101,12 +106,29 @@ public final class TestDays360 {
// 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
* @param diffs
*/
private static void confirmMonthBoundary(boolean method, int year, int monthNo, int...diffs) {
Date firstDayOfNextMonth = makeDate(year, monthNo+1, 1);
@ -120,11 +142,9 @@ public final class TestDays360 {
}
private static void confirm(int expResult, Date firstArg, Date secondArg, boolean method) {
ValueEval ve;
if (method) {
// TODO enable 3rd arg -
ve = invokeDays360(convert(firstArg), convert(secondArg), BoolEval.valueOf(method));
ve = invokeDays360(convert(firstArg), convert(secondArg), BoolEval.TRUE);
} else {
ve = invokeDays360(convert(firstArg), convert(secondArg));
}
@ -143,4 +163,3 @@ public final class TestDays360 {
return new NumberEval(HSSFDateUtil.getExcelDate(d));
}
}