001/*
002 * ObjectLab, http://www.objectlab.co.uk/open is sponsoring the ObjectLab Kit.
003 *
004 * Based in London, we are world leaders in the design and development
005 * of bespoke applications for the securities financing markets.
006 *
007 * <a href="http://www.objectlab.co.uk/open">Click here to learn more</a>
008 *           ___  _     _           _   _          _
009 *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
010 *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
011 *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
012 *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
013 *                   |__/
014 *
015 *                     www.ObjectLab.co.uk
016 *
017 * $Id$
018 *
019 * Copyright 2006 the original author or authors.
020 *
021 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
022 * use this file except in compliance with the License. You may obtain a copy of
023 * the License at
024 *
025 * http://www.apache.org/licenses/LICENSE-2.0
026 *
027 * Unless required by applicable law or agreed to in writing, software
028 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
029 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
030 * License for the specific language governing permissions and limitations under
031 * the License.
032 */
033package net.objectlab.kit.datecalc.common;
034
035import java.util.ArrayList;
036import java.util.List;
037
038/**
039 * Abstract implementation in order to encapsulate all the common functionality
040 * between Jdk and Joda implementations. It is parameterized on &lt;E&gt;
041 * but basically <code>Date</code> and <code>LocalDate</code> are the only
042 * viable values for it for now.
043 *
044 * @author Marcin Jekot
045 *
046 * @param <E>
047 *            a representation of a date, typically JDK: Date, Calendar;
048 *            Joda:LocalDate, YearMonthDay
049 *
050 */
051public abstract class AbstractIMMDateCalculator<E> implements IMMDateCalculator<E> {
052
053    protected static final int MONTHS_IN_QUARTER = 3;
054
055    protected static final int MONTH_IN_YEAR = 12;
056
057    protected static final int DAYS_IN_WEEK = 7;
058
059    /**
060     * @param startDate
061     * @return the next IMMDate based on current date.
062     */
063    @Override
064    public E getNextIMMDate(final E startDate) {
065        return getNextIMMDate(true, startDate, IMMPeriod.QUARTERLY);
066    }
067
068    /**
069     * @param startDate
070     * @param period
071     *            specify when the "next" IMM is, if quarterly then it is the
072     *            conventional algorithm.
073     * @return the next IMMDate based on current date.
074     */
075    @Override
076    public E getNextIMMDate(final E startDate, final IMMPeriod period) {
077        return getNextIMMDate(true, startDate, period);
078    }
079
080    // -----------------------------------------------------------------------
081    //
082    // ObjectLab, world leaders in the design and development of bespoke
083    // applications for the securities financing markets.
084    // www.ObjectLab.co.uk
085    //
086    // -----------------------------------------------------------------------
087
088    /**
089     * @param startDate
090     * @return the previous IMMDate based on current date.
091     */
092    @Override
093    public E getPreviousIMMDate(final E startDate) {
094        return getNextIMMDate(false, startDate, IMMPeriod.QUARTERLY);
095    }
096
097    /**
098     * @param startDate
099     * @param period
100     *            specify when the "previous" IMM is, if quarterly then it is
101     *            the conventional algorithm.
102     * @return the previous IMMDate based on current date.
103     */
104    @Override
105    public E getPreviousIMMDate(final E startDate, final IMMPeriod period) {
106        return getNextIMMDate(false, startDate, period);
107    }
108
109    /**
110     * Returns a list of IMM dates between 2 dates, it will exclude the start
111     * date if it is an IMM date but would include the end date if it is an IMM
112     * (same as IMMPeriod.QUARTERLY).
113     *
114     * @param start
115     *            start of the interval, excluded
116     * @param end
117     *            end of the interval, may be included.
118     * @return list of IMM dates
119     */
120    @Override
121    public List<E> getIMMDates(final E start, final E end) {
122        return getIMMDates(start, end, IMMPeriod.QUARTERLY);
123    }
124
125    /**
126     * Returns a list of N IMM dates from a given date, it will exclude the start
127     * date if it is an IMM date
128     * (same as as calling getIMMDates(start,end,IMMPeriod.QUARTERLY)).
129     *
130     * @param start
131     *            start of the interval, excluded
132     * @param numberOfDates
133     *            number of IMM dates to return.
134     * @return list of IMM dates
135     * @since 1.4.0
136     */
137    @Override
138    public List<E> getNextIMMDates(final E start, final int numberOfDates) {
139        if (numberOfDates < 0) {
140            throw new IllegalArgumentException("numberOfDates cannot be < 0 (" + numberOfDates + ")");
141        }
142        final List<E> dates = new ArrayList<>(numberOfDates);
143
144        E date = start;
145        for (int i = 0; i < numberOfDates; i++) {
146            date = getNextIMMDate(true, date, IMMPeriod.QUARTERLY);
147            dates.add(date);
148        }
149
150        return dates;
151    }
152
153    protected abstract E getNextIMMDate(final boolean requestNextIMM, final E theStartDate, final IMMPeriod period);
154}
155
156/*
157 * ObjectLab, http://www.objectlab.co.uk/open is sponsoring the ObjectLab Kit.
158 *
159 * Based in London, we are world leaders in the design and development
160 * of bespoke applications for the securities financing markets.
161 *
162 * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a>
163 *           ___  _     _           _   _          _
164 *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
165 *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
166 *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
167 *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
168 *                   |__/
169 *
170 *                     www.ObjectLab.co.uk
171 */