From 8def7307d905f83b320f858dded8710127a3bf09 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Fri, 30 Dec 2016 15:05:14 +0000 Subject: [PATCH] Bug 60452: WorkdayCalculator calculateWorkdays does return wrong value for same day input deprecate unused method isNonWorkday git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1776588 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/formula/atp/WorkdayCalculator.java | 28 +++++----- .../ss/formula/atp/TestWorkdayCalculator.java | 53 ++++++++++++++++++- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java b/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java index 29b29feaa..326a7e02f 100644 --- a/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java +++ b/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java @@ -22,6 +22,7 @@ import java.util.Date; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.util.LocaleUtil; +import org.apache.poi.util.Removal; /** * A calculator for workdays, considering dates as excel representations. @@ -38,7 +39,7 @@ public class WorkdayCalculator { /** * Calculate how many workdays are there between a start and an end date, as excel representations, considering a range of holidays. - * + * * @param start start date. * @param end end date. * @param holidays an array of holidays. @@ -53,7 +54,7 @@ public class WorkdayCalculator { /** * Calculate the workday past x workdays from a starting date, considering a range of holidays. - * + * * @param start start date. * @param workdays number of workdays to be past from starting date. * @param holidays an array of holidays. @@ -76,10 +77,10 @@ public class WorkdayCalculator { } return endDate.getTime(); } - + /** * Calculates how many days of week past between a start and an end date. - * + * * @param start start date. * @param end end date. * @param dayOfWeek a day of week as represented by {@link Calendar} constants. @@ -96,12 +97,12 @@ public class WorkdayCalculator { pastDaysOfWeek++; } } - return start < end ? pastDaysOfWeek : -pastDaysOfWeek; + return start <= end ? pastDaysOfWeek : -pastDaysOfWeek; } /** * Calculates how many holidays in a list are workdays, considering an interval of dates. - * + * * @param start start date. * @param end end date. * @param holidays an array of holidays. @@ -111,14 +112,14 @@ public class WorkdayCalculator { int nonWeekendHolidays = 0; double startDay = start < end ? start : end; double endDay = end > start ? end : start; - for (int i = 0; i < holidays.length; i++) { - if (isInARange(startDay, endDay, holidays[i])) { - if (!isWeekend(holidays[i])) { + for (double holiday : holidays) { + if (isInARange(startDay, endDay, holiday)) { + if (!isWeekend(holiday)) { nonWeekendHolidays++; } } } - return start < end ? nonWeekendHolidays : -nonWeekendHolidays; + return start <= end ? nonWeekendHolidays : -nonWeekendHolidays; } /** @@ -137,8 +138,8 @@ public class WorkdayCalculator { * @return true if date is a holiday, false otherwise. */ protected boolean isHoliday(double aDate, double[] holidays) { - for (int i = 0; i < holidays.length; i++) { - if (Math.round(holidays[i]) == Math.round(aDate)) { + for (double holiday : holidays) { + if (Math.round(holiday) == Math.round(aDate)) { return true; } } @@ -149,7 +150,10 @@ public class WorkdayCalculator { * @param aDate a given date. * @param holidays an array of holidays. * @return 1 is not a workday, 0 otherwise. + * + * @deprecated POI 3.16 - will be removed, not used in POI itself */ + @Removal(version="3.18") protected int isNonWorkday(double aDate, double[] holidays) { return isWeekend(aDate) || isHoliday(aDate, holidays) ? 1 : 0; } diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java b/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java index 055149c6c..80adae743 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java @@ -67,6 +67,24 @@ public class TestWorkdayCalculator { assertEquals(4, WorkdayCalculator.instance.calculateWorkdays(A_FRIDAY, A_WEDNESDAY, new double[]{ A_SATURDAY, A_SUNDAY })); } + @Test + public void testCalculateWorkdaysOnSameDayShouldReturn1ForWeekdays() { + final double A_MONDAY = DateUtil.getExcelDate(d(2017, 1, 2)); + assertEquals(1, WorkdayCalculator.instance.calculateWorkdays(A_MONDAY, A_MONDAY, new double[0])); + } + + @Test + public void testCalculateWorkdaysOnSameDayShouldReturn0ForHolidays() { + final double A_MONDAY = DateUtil.getExcelDate(d(2017, 1, 2)); + assertEquals(0, WorkdayCalculator.instance.calculateWorkdays(A_MONDAY, A_MONDAY, new double[]{ A_MONDAY })); + } + + @Test + public void testCalculateWorkdaysOnSameDayShouldReturn0ForWeekends() { + final double A_SUNDAY = DateUtil.getExcelDate(d(2017, 1, 1)); + assertEquals(0, WorkdayCalculator.instance.calculateWorkdays(A_SUNDAY, A_SUNDAY, new double[0])); + } + @Test public void testCalculateWorkdaysNumberOfDays() { double start = 41553.0; @@ -108,9 +126,42 @@ public class TestWorkdayCalculator { final double A_SATURDAY = DateUtil.getExcelDate(d(2011, 12, 10)); assertEquals(1, WorkdayCalculator.instance.pastDaysOfWeek(A_THURSDAY, A_SATURDAY, SATURDAY)); } - + private static Date d(int year, int month, int day) { Calendar cal = LocaleUtil.getLocaleCalendar(year, month-1, day, 0, 0, 0); return cal.getTime(); } + + @Test + public void testCalculateNonWeekendHolidays() { + final double start = DateUtil.getExcelDate(d(2016, 12, 24)); + final double end = DateUtil.getExcelDate(d(2016, 12, 31)); + final double holiday1 = DateUtil.getExcelDate(d(2016, 12, 25)); + final double holiday2 = DateUtil.getExcelDate(d(2016, 12, 26)); + int count = WorkdayCalculator.instance.calculateNonWeekendHolidays(start, end, new double[]{holiday1, holiday2}); + assertEquals("Expected 1 non-weekend-holiday for " + start + " to " + end + " and " + holiday1 + " and " + holiday2, + 1, count); + } + + @Test + public void testCalculateNonWeekendHolidaysOneDay() { + final double start = DateUtil.getExcelDate(d(2016, 12, 26)); + final double end = DateUtil.getExcelDate(d(2016, 12, 26)); + final double holiday1 = DateUtil.getExcelDate(d(2016, 12, 25)); + final double holiday2 = DateUtil.getExcelDate(d(2016, 12, 26)); + int count = WorkdayCalculator.instance.calculateNonWeekendHolidays(start, end, new double[]{holiday1, holiday2}); + assertEquals("Expected 1 non-weekend-holiday for " + start + " to " + end + " and " + holiday1 + " and " + holiday2, + 1, count); + } + + @SuppressWarnings("deprecation") + @Test + public void testIsNonWorkday() throws Exception { + final double weekend = DateUtil.getExcelDate(d(2016, 12, 25)); + final double holiday = DateUtil.getExcelDate(d(2016, 12, 26)); + final double workday = DateUtil.getExcelDate(d(2016, 12, 27)); + assertEquals(1, WorkdayCalculator.instance.isNonWorkday(weekend, new double[]{holiday})); + assertEquals(1, WorkdayCalculator.instance.isNonWorkday(holiday, new double[]{holiday})); + assertEquals(0, WorkdayCalculator.instance.isNonWorkday(workday, new double[]{holiday})); + } }