View Javadoc
1   /*
2    * ObjectLab, http://www.objectlab.co.uk/open is sponsoring the ObjectLab Kit.
3    *
4    * Based in London, we are world leaders in the design and development
5    * of bespoke applications for the securities financing markets.
6    *
7    * <a href="http://www.objectlab.co.uk/open">Click here to learn more</a>
8    *           ___  _     _           _   _          _
9    *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
10   *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
11   *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
12   *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
13   *                   |__/
14   *
15   *                     www.ObjectLab.co.uk
16   *
17   * $Id$
18   *
19   * Copyright 2006 the original author or authors.
20   *
21   * Licensed under the Apache License, Version 2.0 (the "License"); you may not
22   * use this file except in compliance with the License. You may obtain a copy of
23   * the License at
24   *
25   * http://www.apache.org/licenses/LICENSE-2.0
26   *
27   * Unless required by applicable law or agreed to in writing, software
28   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
29   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
30   * License for the specific language governing permissions and limitations under
31   * the License.
32   */
33  package net.objectlab.kit.datecalc.jdk;
34  
35  import java.util.Calendar;
36  import java.util.Collections;
37  import java.util.Date;
38  
39  import net.objectlab.kit.datecalc.common.AbstractDateCalculator;
40  import net.objectlab.kit.datecalc.common.DateCalculator;
41  import net.objectlab.kit.datecalc.common.DefaultHolidayCalendar;
42  import net.objectlab.kit.datecalc.common.HolidayCalendar;
43  import net.objectlab.kit.datecalc.common.HolidayHandler;
44  import net.objectlab.kit.datecalc.common.Utils;
45  import net.objectlab.kit.datecalc.common.WorkingWeek;
46  
47  /**
48   * This class is used via the DateCalculator interface, it enables the handling
49   * of different HolidayHandler, if no HolidayHandler is defined, the calendar
50   * will NOT move a date, even if it falls on a holiday or weekend.
51   *
52   * @author Marcin Jekot
53   */
54  public class DateDateCalculator extends AbstractDateCalculator<Date> {
55  
56      private final CalendarDateCalculator delegate;
57  
58      public DateDateCalculator() {
59          this(null, null, new DefaultHolidayCalendar<Date>(Collections.<Date> emptySet()), null);
60      }
61  
62      public DateDateCalculator(final String name, final Date startDate, final HolidayCalendar<Date> holidayCalendar,
63              final HolidayHandler<Date> holidayHandler) {
64          super(name, holidayCalendar, holidayHandler);
65          Date date = startDate;
66          final HolidayHandler<Calendar> locDate = new HolidayHandlerDateWrapper(holidayHandler, this);
67  
68          final HolidayCalendar<Calendar> nonWorkingCalendars = Utils.toHolidayCalendarSet(holidayCalendar);
69          if (date == null) {
70              date = getToday();
71          }
72  
73          delegate = new CalendarDateCalculator(name, Utils.getCal(date), nonWorkingCalendars, locDate);
74          delegate.setStartDate(Utils.getCal(date));
75          if (date != null) {
76              setStartDate(date);
77          }
78      }
79  
80      // -----------------------------------------------------------------------
81      //
82      // ObjectLab, world leaders in the design and development of bespoke
83      // applications for the securities financing markets.
84      // www.ObjectLab.co.uk
85      //
86      // -----------------------------------------------------------------------
87  
88      // TODO throw an exception if the type is incorrect
89      @Override
90      public DateCalculator<Date> setWorkingWeek(final WorkingWeek week) {
91          delegate.setWorkingWeek(week);
92          return this;
93      }
94  
95      /**
96       * is the date a non-working day according to the WorkingWeek?
97       */
98      @Override
99      public boolean isWeekend(final Date date) {
100         if (date != null && delegate != null) {
101             return delegate.isWeekend(Utils.getCal(date));
102         }
103         return false;
104     }
105 
106     @Override
107     public DateCalculator<Date> moveByDays(final int days) {
108         setCurrentIncrement(days);
109         delegate.setCurrentIncrement(days);
110         delegate.setCurrentBusinessDate(Utils.getCal(getCurrentBusinessDate()));
111         setCurrentBusinessDate(delegate.moveByDays(days).getCurrentBusinessDate().getTime());
112         return this;
113     }
114 
115     @Override
116     protected DateCalculator<Date> createNewCalculator(final String name, final Date startDate, final HolidayCalendar<Date> holidays,
117             final HolidayHandler<Date> handler) {
118         return new DateDateCalculator(name, startDate, holidays, handler);
119     }
120 
121     @Override
122     public final DateCalculator<Date> setStartDate(final Date startDate) {
123         if (delegate != null) {
124             delegate.setStartDate(startDate != null ? Utils.getCal(startDate) : null);
125         }
126         super.setStartDate(startDate);
127         return this;
128     }
129 
130     @Override
131     protected final Date getToday() {
132         return Utils.blastTime(Calendar.getInstance()).getTime();
133     }
134 
135     @Override
136     protected DateCalculator<Date> moveByMonths(final int months) {
137         setCurrentIncrement(months);
138         delegate.setCurrentIncrement(months);
139         delegate.setCurrentBusinessDate(Utils.getCal(getCurrentBusinessDate()));
140         setCurrentBusinessDate(delegate.moveByMonths(months).getCurrentBusinessDate().getTime());
141         return this;
142     }
143 
144     @Override
145     protected Date compareDate(final Date date1, final Date date2, final boolean returnEarliest) {
146         if (date1 == null || date2 == null) {
147             return null;
148         }
149         if (returnEarliest) {
150             return date1.after(date2) ? date2 : date1;
151         } else {
152             return date2.after(date1) ? date2 : date1;
153         }
154     }
155 
156     @Override
157     protected void checkBoundary(final Date date) {
158         final Date early = getHolidayCalendar().getEarlyBoundary();
159         if (early != null && early.after(date)) {
160             throw new IndexOutOfBoundsException(date + " is before the early boundary " + early);
161         }
162 
163         final Date late = getHolidayCalendar().getLateBoundary();
164         if (late != null && late.before(date)) {
165             throw new IndexOutOfBoundsException(date + " is after the late boundary " + late);
166         }
167     }
168 
169     @Override
170     protected Date clone(final Date date) {
171         return new Date(date.getTime());
172     }
173 
174     @Override
175     public int getNumberOfBusinessDaysBetween(final Date d1, final Date d2) {
176         if (d1 == null || d2 == null) {
177             return 0;
178         }
179         final boolean d1B4d2 = !d1.after(d2);
180         Calendar start = Utils.getCal(d1B4d2 ? d1 : d2);
181         final Calendar end = Utils.getCal(d1B4d2 ? d2 : d1);
182         if (getHolidayHandler() != null) {
183             start = Utils.getCal(getHolidayHandler().adjustDate(start.getTime(), 1, this));
184         }
185 
186         int count = 0;
187 
188         while (start.before(end)) {
189             if (!isNonWorkingDay(start.getTime())) {
190                 count++;
191             }
192             start.add(Calendar.DATE, 1);
193         }
194         return d1B4d2 ? count : -count;
195     }
196 }
197 
198 /*
199  * ObjectLab, http://www.objectlab.co.uk/open is sponsoring the ObjectLab Kit.
200  *
201  * Based in London, we are world leaders in the design and development
202  * of bespoke applications for the securities financing markets.
203  *
204  * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a>
205  *           ___  _     _           _   _          _
206  *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
207  *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
208  *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
209  *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
210  *                   |__/
211  *
212  *                     www.ObjectLab.co.uk
213  */