QuarterlyScheduleCalculator extends Schedule { @Override public LocalDate[] getSchedule(final LocalDate startDate, final LocalDate endDate, final boolean fromEnd, final boolean generateRecursive) { ArgumentChecker.notNull(startDate, "start date"); ArgumentChecker.notNull(endDate, "end date"); ArgumentChecker.isFalse(startDate.isAfter(endDate), "start date must not be after end date"); if (startDate.equals(endDate)) { return new LocalDate[] {startDate}; } final List<LocalDate> dates = new ArrayList<>(); if (fromEnd) { LocalDate date = endDate; int i = 3; while (!date.isBefore(startDate)) { dates.add(date); date = generateRecursive ? date.minusMonths(3) : endDate.minusMonths(i); i += 3; } Collections.reverse(dates); return dates.toArray(EMPTY_LOCAL_DATE_ARRAY); } LocalDate date = startDate; int i = 3; while (!date.isAfter(endDate)) { dates.add(date); date = generateRecursive ? date.plusMonths(3) : startDate.plusMonths(i); i += 3; } return dates.toArray(EMPTY_LOCAL_DATE_ARRAY); }  @Override LocalDate[] getSchedule(final LocalDate startDate, final LocalDate endDate, final boolean fromEnd, final boolean generateRecursive); @Override ZonedDateTime[] getSchedule(final ZonedDateTime startDate, final ZonedDateTime endDate, final boolean fromEnd, final boolean generateRecursive);  }
@Test public void testStartAndEndEqual1() { final LocalDate date = LocalDate.of(2010, 1, 1); final LocalDate[] result = CALCULATOR.getSchedule(date, date, true, true); assertEquals(result.length, 1); assertEquals(result[0], date); }
@Test public void testStartAndEndEqual2() { final ZonedDateTime date = DateUtils.getUTCDate(2010, 1, 1); final ZonedDateTime[] result = CALCULATOR.getSchedule(date, date, true, true); assertEquals(result.length, 1); assertEquals(result[0], date); }
@Test public void test1() { LocalDate startDate = LocalDate.of(2000, 1, 1); LocalDate endDate = LocalDate.of(2000, 3, 30); LocalDate[] forward = CALCULATOR.getSchedule(startDate, endDate, false, false); LocalDate[] backward = CALCULATOR.getSchedule(startDate, endDate, true, false); assertEquals(forward.length, 1); assertEquals(backward.length, 1); assertEquals(forward[0], startDate); assertEquals(backward[0], endDate); startDate = LocalDate.of(2000, 1, 1); endDate = LocalDate.of(2002, 4, 9); final int quarters = 10; forward = CALCULATOR.getSchedule(startDate, endDate, false, false); backward = CALCULATOR.getSchedule(startDate, endDate, true, false); assertEquals(forward.length, quarters); assertEquals(backward.length, quarters); assertEquals(forward[0], startDate); assertEquals(backward[0], LocalDate.of(2000, 1, 9)); assertEquals(forward[quarters - 1], LocalDate.of(2002, 4, 1)); assertEquals(backward[quarters - 1], endDate); for (int i = 1; i < quarters; i++) { if (forward[i].getYear() == forward[i - 1].getYear()) { assertEquals(forward[i].getMonthValue() - forward[i - 1].getMonthValue(), 3); assertEquals(backward[i].getMonthValue() - backward[i - 1].getMonthValue(), 3); } else { assertEquals(forward[i].getMonthValue() - forward[i - 1].getMonthValue(), -9); assertEquals(backward[i].getMonthValue() - backward[i - 1].getMonthValue(), -9); } assertEquals(forward[i].getDayOfMonth(), 1); assertEquals(backward[i].getDayOfMonth(), 9); } }
@Test public void test2() { ZonedDateTime startDate = DateUtils.getUTCDate(2000, 1, 1); ZonedDateTime endDate = DateUtils.getUTCDate(2000, 3, 30); ZonedDateTime[] forward = CALCULATOR.getSchedule(startDate, endDate, false, false); ZonedDateTime[] backward = CALCULATOR.getSchedule(startDate, endDate, true, false); assertEquals(forward.length, 1); assertEquals(backward.length, 1); assertEquals(forward[0], startDate); assertEquals(backward[0], endDate); startDate = DateUtils.getUTCDate(2000, 1, 1); endDate = DateUtils.getUTCDate(2002, 4, 9); final int quarters = 10; forward = CALCULATOR.getSchedule(startDate, endDate, false, false); backward = CALCULATOR.getSchedule(startDate, endDate, true, false); assertEquals(forward.length, quarters); assertEquals(backward.length, quarters); assertEquals(forward[0], startDate); assertEquals(backward[0], DateUtils.getUTCDate(2000, 1, 9)); assertEquals(forward[quarters - 1], DateUtils.getUTCDate(2002, 4, 1)); assertEquals(backward[quarters - 1], endDate); for (int i = 1; i < quarters; i++) { if (forward[i].getYear() == forward[i - 1].getYear()) { assertEquals(forward[i].getMonthValue() - forward[i - 1].getMonthValue(), 3); assertEquals(backward[i].getMonthValue() - backward[i - 1].getMonthValue(), 3); } else { assertEquals(forward[i].getMonthValue() - forward[i - 1].getMonthValue(), -9); assertEquals(backward[i].getMonthValue() - backward[i - 1].getMonthValue(), -9); } assertEquals(forward[i].getDayOfMonth(), 1); assertEquals(backward[i].getDayOfMonth(), 9); } }
@Test public void testEndOfMonth1() { final LocalDate startDate = LocalDate.of(2008, 11, 30); final LocalDate endDate = LocalDate.of(2010, 8, 31); final LocalDate[] fromStart = new LocalDate[] {LocalDate.of(2008, 11, 30), LocalDate.of(2009, 2, 28), LocalDate.of(2009, 5, 30), LocalDate.of(2009, 8, 30), LocalDate.of(2009, 11, 30), LocalDate.of(2010, 2, 28), LocalDate.of(2010, 5, 30), LocalDate.of(2010, 8, 30)}; final LocalDate[] fromStartRecursive = new LocalDate[] {LocalDate.of(2008, 11, 30), LocalDate.of(2009, 2, 28), LocalDate.of(2009, 5, 28), LocalDate.of(2009, 8, 28), LocalDate.of(2009, 11, 28), LocalDate.of(2010, 2, 28), LocalDate.of(2010, 5, 28), LocalDate.of(2010, 8, 28)}; final LocalDate[] fromEnd = new LocalDate[] {LocalDate.of(2008, 11, 30), LocalDate.of(2009, 2, 28), LocalDate.of(2009, 5, 31), LocalDate.of(2009, 8, 31), LocalDate.of(2009, 11, 30), LocalDate.of(2010, 2, 28), LocalDate.of(2010, 5, 31), LocalDate.of(2010, 8, 31)}; final LocalDate[] fromEndRecursive = new LocalDate[] {LocalDate.of(2009, 2, 28), LocalDate.of(2009, 5, 28), LocalDate.of(2009, 8, 28), LocalDate.of(2009, 11, 28), LocalDate.of(2010, 2, 28), LocalDate.of(2010, 5, 31), LocalDate.of(2010, 8, 31)}; assertArrayEquals(fromStart, CALCULATOR.getSchedule(startDate, endDate, false, false)); assertArrayEquals(fromStartRecursive, CALCULATOR.getSchedule(startDate, endDate, false, true)); assertArrayEquals(fromEnd, CALCULATOR.getSchedule(startDate, endDate, true, false)); assertArrayEquals(fromEndRecursive, CALCULATOR.getSchedule(startDate, endDate, true, true)); }
@Test public void testEndOfMonth2() { final ZonedDateTime startDate = DateUtils.getUTCDate(2008, 11, 30); final ZonedDateTime endDate = DateUtils.getUTCDate(2010, 8, 31); final ZonedDateTime[] fromStart = new ZonedDateTime[] {DateUtils.getUTCDate(2008, 11, 30), DateUtils.getUTCDate(2009, 2, 28), DateUtils.getUTCDate(2009, 5, 30), DateUtils.getUTCDate(2009, 8, 30), DateUtils.getUTCDate(2009, 11, 30), DateUtils.getUTCDate(2010, 2, 28), DateUtils.getUTCDate(2010, 5, 30), DateUtils.getUTCDate(2010, 8, 30)}; final ZonedDateTime[] fromStartRecursive = new ZonedDateTime[] {DateUtils.getUTCDate(2008, 11, 30), DateUtils.getUTCDate(2009, 2, 28), DateUtils.getUTCDate(2009, 5, 28), DateUtils.getUTCDate(2009, 8, 28), DateUtils.getUTCDate(2009, 11, 28), DateUtils.getUTCDate(2010, 2, 28), DateUtils.getUTCDate(2010, 5, 28), DateUtils.getUTCDate(2010, 8, 28)}; final ZonedDateTime[] fromEnd = new ZonedDateTime[] {DateUtils.getUTCDate(2008, 11, 30), DateUtils.getUTCDate(2009, 2, 28), DateUtils.getUTCDate(2009, 5, 31), DateUtils.getUTCDate(2009, 8, 31), DateUtils.getUTCDate(2009, 11, 30), DateUtils.getUTCDate(2010, 2, 28), DateUtils.getUTCDate(2010, 5, 31), DateUtils.getUTCDate(2010, 8, 31)}; final ZonedDateTime[] fromEndRecursive = new ZonedDateTime[] {DateUtils.getUTCDate(2009, 2, 28), DateUtils.getUTCDate(2009, 5, 28), DateUtils.getUTCDate(2009, 8, 28), DateUtils.getUTCDate(2009, 11, 28), DateUtils.getUTCDate(2010, 2, 28), DateUtils.getUTCDate(2010, 5, 31), DateUtils.getUTCDate(2010, 8, 31)}; assertArrayEquals(fromStart, CALCULATOR.getSchedule(startDate, endDate, false, false)); assertArrayEquals(fromStartRecursive, CALCULATOR.getSchedule(startDate, endDate, false, true)); assertArrayEquals(fromEnd, CALCULATOR.getSchedule(startDate, endDate, true, false)); assertArrayEquals(fromEndRecursive, CALCULATOR.getSchedule(startDate, endDate, true, true)); }