@Override public double calculateYearFraction(LocalDate firstDate, LocalDate secondDate, ScheduleInfo scheduleInfo) { long actualDays = daysBetween(firstDate, secondDate); int numberOfLeapDays = 0; LocalDate temp = DateAdjusters.nextLeapDay(firstDate); while (temp.isAfter(secondDate) == false) { numberOfLeapDays++; temp = DateAdjusters.nextLeapDay(temp); } return (actualDays - numberOfLeapDays) / 365d; }
@Override public int calculateDays(LocalDate firstDate, LocalDate secondDate) { long actualDays = daysBetween(firstDate, secondDate); int numberOfLeapDays = 0; LocalDate temp = DateAdjusters.nextLeapDay(firstDate); while (temp.isAfter(secondDate) == false) { numberOfLeapDays++; temp = DateAdjusters.nextLeapDay(temp); } return toIntExact(actualDays) - numberOfLeapDays; } },
@Override public double calculateYearFraction(LocalDate firstDate, LocalDate secondDate, ScheduleInfo scheduleInfo) { long actualDays = daysBetween(firstDate, secondDate); LocalDate nextLeap = DateAdjusters.nextLeapDay(firstDate); return actualDays / (nextLeap.isAfter(secondDate) ? 365d : 366d); }
@Test(dataProvider = "nextLeapDay") public void test_nextLeapDay_LocalDate(int year, int month, int day, int expectedYear) { LocalDate date = LocalDate.of(year, month, day); LocalDate test = DateAdjusters.nextLeapDay().adjust(date); assertEquals(test.getYear(), expectedYear); assertEquals(test.getMonthValue(), 2); assertEquals(test.getDayOfMonth(), 29); }
@Test(dataProvider = "nextLeapDay") public void test_nextLeapDay_Temporal(int year, int month, int day, int expectedYear) { LocalDate date = LocalDate.of(year, month, day); LocalDate test = (LocalDate) DateAdjusters.nextLeapDay().adjustInto(date); assertEquals(test.getYear(), expectedYear); assertEquals(test.getMonthValue(), 2); assertEquals(test.getDayOfMonth(), 29); }
@Override public double calculateYearFraction(LocalDate firstDate, LocalDate secondDate, ScheduleInfo scheduleInfo) { long actualDays = daysBetween(firstDate, secondDate); // avoid using ScheduleInfo in this case if (firstDate.equals(secondDate)) { return 0d; } // calculation is based on the end of the schedule period (next coupon date) and annual/non-annual frequency LocalDate nextCouponDate = scheduleInfo.getPeriodEndDate(firstDate); if (scheduleInfo.getFrequency().isAnnual()) { LocalDate nextLeap = DateAdjusters.nextLeapDay(firstDate); return actualDays / (nextLeap.isAfter(nextCouponDate) ? 365d : 366d); } else { return actualDays / (nextCouponDate.isLeapYear() ? 366d : 365d); } }