Bug 55649: WORKDAY Function returns incorrect date when spanning a weekend, or the start date is a weekend
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1531124 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f15a35ec45
commit
61f1130e38
@ -61,24 +61,24 @@ public class WorkdayCalculator {
|
|||||||
* @param holidays an array of holidays.
|
* @param holidays an array of holidays.
|
||||||
* @return date past x workdays.
|
* @return date past x workdays.
|
||||||
*/
|
*/
|
||||||
public Date calculateWorkdays(double start, int workdays, double[] holidays) {
|
public Date calculateWorkdays(double start, int workdays, double[] holidays) {
|
||||||
Date startDate = DateUtil.getJavaDate(start);
|
Date startDate = DateUtil.getJavaDate(start);
|
||||||
Calendar endDate = Calendar.getInstance();
|
int direction = workdays < 0 ? -1 : 1;
|
||||||
endDate.setTime(startDate);
|
Calendar endDate = Calendar.getInstance();
|
||||||
endDate.add(Calendar.DAY_OF_YEAR, workdays);
|
endDate.setTime(startDate);
|
||||||
int skippedDays = 0;
|
double excelEndDate = DateUtil.getExcelDate(endDate.getTime());
|
||||||
do {
|
while (workdays != 0) {
|
||||||
double end = DateUtil.getExcelDate(endDate.getTime());
|
endDate.add(Calendar.DAY_OF_YEAR, direction);
|
||||||
int saturdaysPast = this.pastDaysOfWeek(start, end, Calendar.SATURDAY);
|
excelEndDate += direction;
|
||||||
int sundaysPast = this.pastDaysOfWeek(start, end, Calendar.SUNDAY);
|
if (endDate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
|
||||||
int nonWeekendHolidays = this.calculateNonWeekendHolidays(start, end, holidays);
|
&& endDate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY
|
||||||
skippedDays = saturdaysPast + sundaysPast + nonWeekendHolidays;
|
&& !isHoliday(excelEndDate, holidays)) {
|
||||||
endDate.add(Calendar.DAY_OF_YEAR, skippedDays);
|
workdays -= direction;
|
||||||
start = end + isNonWorkday(end, holidays);
|
}
|
||||||
} while (skippedDays != 0);
|
}
|
||||||
return endDate.getTime();
|
return endDate.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates how many days of week past between a start and an end date.
|
* Calculates how many days of week past between a start and an end date.
|
||||||
*
|
*
|
||||||
|
@ -85,6 +85,46 @@ public class TestWorkdayFunction extends TestCase {
|
|||||||
new StringEval(STARTING_DATE.toString()), new NumberEval(151) }, EC)).getNumberValue()));
|
new StringEval(STARTING_DATE.toString()), new NumberEval(151) }, EC)).getNumberValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testReturnWorkdaysSpanningAWeekendSubtractingDays() {
|
||||||
|
String startDate = "2013/09/30";
|
||||||
|
int days = -1;
|
||||||
|
String expectedWorkDay = "2013/09/27";
|
||||||
|
StringEval stringEval = new StringEval(startDate);
|
||||||
|
double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{
|
||||||
|
stringEval, new NumberEval(days) }, EC)).getNumberValue();
|
||||||
|
assertEquals(expectedWorkDay, formatter.format(DateUtil.getJavaDate(numberValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReturnWorkdaysSpanningAWeekendAddingDays() {
|
||||||
|
String startDate = "2013/09/27";
|
||||||
|
int days = 1;
|
||||||
|
String expectedWorkDay = "2013/09/30";
|
||||||
|
StringEval stringEval = new StringEval(startDate);
|
||||||
|
double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{
|
||||||
|
stringEval, new NumberEval(days) }, EC)).getNumberValue();
|
||||||
|
assertEquals(expectedWorkDay, formatter.format(DateUtil.getJavaDate(numberValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReturnWorkdaysWhenStartIsWeekendAddingDays() {
|
||||||
|
String startDate = "2013/10/06";
|
||||||
|
int days = 1;
|
||||||
|
String expectedWorkDay = "2013/10/07";
|
||||||
|
StringEval stringEval = new StringEval(startDate);
|
||||||
|
double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{
|
||||||
|
stringEval, new NumberEval(days) }, EC)).getNumberValue();
|
||||||
|
assertEquals(expectedWorkDay, formatter.format(DateUtil.getJavaDate(numberValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReturnWorkdaysWhenStartIsWeekendSubtractingDays() {
|
||||||
|
String startDate = "2013/10/06";
|
||||||
|
int days = -1;
|
||||||
|
String expectedWorkDay = "2013/10/04";
|
||||||
|
StringEval stringEval = new StringEval(startDate);
|
||||||
|
double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{
|
||||||
|
stringEval, new NumberEval(days) }, EC)).getNumberValue();
|
||||||
|
assertEquals(expectedWorkDay, formatter.format(DateUtil.getJavaDate(numberValue)));
|
||||||
|
}
|
||||||
|
|
||||||
public void testReturnWorkdaysWithDaysTruncated() {
|
public void testReturnWorkdaysWithDaysTruncated() {
|
||||||
assertEquals(new Date(109, APRIL, 30), DateUtil.getJavaDate(((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{
|
assertEquals(new Date(109, APRIL, 30), DateUtil.getJavaDate(((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{
|
||||||
new StringEval(STARTING_DATE.toString()), new NumberEval(151.99999) }, EC)).getNumberValue()));
|
new StringEval(STARTING_DATE.toString()), new NumberEval(151.99999) }, EC)).getNumberValue()));
|
||||||
|
Loading…
Reference in New Issue
Block a user