/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.convention.daycount; import org.threeten.bp.LocalDate; import org.threeten.bp.Year; /** * */ public class ActualNL extends ActualTypeDayCount { private static final long serialVersionUID = 1L; @Override public double getAccruedInterest(final LocalDate previousCouponDate, final LocalDate date, final LocalDate nextCouponDate, final double coupon, final double paymentsPerYear) { return getDayCountFraction(previousCouponDate, date) * coupon; } @Override public double getDayCountFraction(final LocalDate firstDate, final LocalDate secondDate) { testDates(firstDate, secondDate); long actualDays = secondDate.toEpochDay() - firstDate.toEpochDay(); int numberOfLeapDays = 0; LocalDate temp = nextLeapDay(firstDate); while (temp.isAfter(secondDate) == false) { numberOfLeapDays++; temp = nextLeapDay(temp); } return (actualDays - numberOfLeapDays) / 365d; } // finds the next leap day after the input date private static LocalDate nextLeapDay(LocalDate input) { // already a leap day, move forward either 4 or 8 years if (input.getMonthValue() == 2 && input.getDayOfMonth() == 29) { return ensureLeapDay(input.getYear() + 4); } // handle if before February 29 in a leap year if (input.isLeapYear() && input.getMonthValue() <= 2) { return LocalDate.of(input.getYear(), 2, 29); } // handle any other date return ensureLeapDay(((input.getYear() / 4) * 4) + 4); } // handle 2100, which is not a leap year private static LocalDate ensureLeapDay(int possibleLeapYear) { if (Year.isLeap(possibleLeapYear)) { return LocalDate.of(possibleLeapYear, 2, 29); } else { return LocalDate.of(possibleLeapYear + 4, 2, 29); } } @Override public String getName() { return "Actual/NL"; } }