/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.credit; import java.util.Set; import org.threeten.bp.DayOfWeek; import org.threeten.bp.LocalDate; import org.threeten.bp.Month; import org.threeten.bp.ZonedDateTime; import org.threeten.bp.temporal.ChronoUnit; import org.threeten.bp.temporal.Temporal; import org.threeten.bp.temporal.TemporalAdjuster; import org.threeten.bp.temporal.TemporalAdjusters; import com.google.common.collect.ImmutableSet; import com.opengamma.financial.analytics.ircurve.NextExpiryAdjuster; import com.opengamma.util.time.Tenor; /** * */ public class IMMDateGenerator { private static final NextExpiryAdjuster IMM_ADJUSTER = new NextExpiryAdjuster(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.WEDNESDAY)); private static final Set<Month> IMM_MONTHS = ImmutableSet.of(Month.MARCH, Month.JUNE, Month.SEPTEMBER, Month.DECEMBER); private static final int TWENTIETH = 20; public static ZonedDateTime getNextIMMDate(final ZonedDateTime date, final Tenor tenor) { // If 19th of month (IMM date - 1 day) we need to cycle to next IMM period, as effective date of trade on date t is t + 1 final ZonedDateTime dateWithTradeAdjustment = ((isIMMDate(date) && date.getDayOfMonth() == TWENTIETH - 1)) ? ZonedDateTime.from(date).plusDays(1) : ZonedDateTime.from(date); final ZonedDateTime nextIMMDate = ZonedDateTime.from(IMM_ADJUSTER.adjustInto(dateWithTradeAdjustment)).withDayOfMonth(TWENTIETH); // must be 20th return nextIMMDate.plus(tenor.getPeriod()); } public static LocalDate getPreviousIMMDate(final LocalDate date) { final TemporalAdjuster adjuster = new TemporalAdjuster() { @Override public Temporal adjustInto(final Temporal temporal) { Temporal adjusted = temporal; do { adjusted = adjusted.minus(1, ChronoUnit.MONTHS); } while (!IMM_MONTHS.contains(Month.from(adjusted))); return adjusted; } }; return date.with(adjuster); } public static boolean isIMMDate(final ZonedDateTime date) { return IMM_MONTHS.contains(date.getMonth()); } }