Author: cedricwalter
Date: Thu Oct 10 21:54:52 2013
New Revision: 1531124
URL: http://svn.apache.org/r1531124
Log:
Bug 55649: WORKDAY Function returns incorrect date when spanning a weekend, or
the start date is a weekend
Modified:
poi/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
poi/trunk/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java
Modified:
poi/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java?rev=1531124&r1=1531123&r2=1531124&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java Thu
Oct 10 21:54:52 2013
@@ -61,24 +61,24 @@ public class WorkdayCalculator {
* @param holidays an array of holidays.
* @return date past x workdays.
*/
- public Date calculateWorkdays(double start, int workdays, double[]
holidays) {
- Date startDate = DateUtil.getJavaDate(start);
- Calendar endDate = Calendar.getInstance();
- endDate.setTime(startDate);
- endDate.add(Calendar.DAY_OF_YEAR, workdays);
- int skippedDays = 0;
- do {
- double end = DateUtil.getExcelDate(endDate.getTime());
- int saturdaysPast = this.pastDaysOfWeek(start, end,
Calendar.SATURDAY);
- int sundaysPast = this.pastDaysOfWeek(start, end, Calendar.SUNDAY);
- int nonWeekendHolidays = this.calculateNonWeekendHolidays(start,
end, holidays);
- skippedDays = saturdaysPast + sundaysPast + nonWeekendHolidays;
- endDate.add(Calendar.DAY_OF_YEAR, skippedDays);
- start = end + isNonWorkday(end, holidays);
- } while (skippedDays != 0);
- return endDate.getTime();
- }
-
+ public Date calculateWorkdays(double start, int workdays, double[]
holidays) {
+ Date startDate = DateUtil.getJavaDate(start);
+ int direction = workdays < 0 ? -1 : 1;
+ Calendar endDate = Calendar.getInstance();
+ endDate.setTime(startDate);
+ double excelEndDate = DateUtil.getExcelDate(endDate.getTime());
+ while (workdays != 0) {
+ endDate.add(Calendar.DAY_OF_YEAR, direction);
+ excelEndDate += direction;
+ if (endDate.get(Calendar.DAY_OF_WEEK) !=
Calendar.SATURDAY
+ && endDate.get(Calendar.DAY_OF_WEEK) !=
Calendar.SUNDAY
+ && !isHoliday(excelEndDate,
holidays)) {
+ workdays -= direction;
+ }
+ }
+ return endDate.getTime();
+ }
+
/**
* Calculates how many days of week past between a start and an end date.
*
Modified:
poi/trunk/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java?rev=1531124&r1=1531123&r2=1531124&view=diff
==============================================================================
---
poi/trunk/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java
(original)
+++
poi/trunk/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java
Thu Oct 10 21:54:52 2013
@@ -85,6 +85,46 @@ public class TestWorkdayFunction extends
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() {
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()));
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]