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.jdk8; 034 035import java.time.LocalDate; 036import java.util.Collections; 037 038import net.objectlab.kit.datecalc.common.AbstractDateCalculator; 039import net.objectlab.kit.datecalc.common.DateCalculator; 040import net.objectlab.kit.datecalc.common.DefaultHolidayCalendar; 041import net.objectlab.kit.datecalc.common.HolidayCalendar; 042import net.objectlab.kit.datecalc.common.HolidayHandler; 043import net.objectlab.kit.datecalc.common.WorkingWeek; 044 045/** 046 * This class is used via the DateCalculator interface, it enables the handling 047 * of different HolidayHandler, if no HolidayHandler is defined, the calendar 048 * will NOT move a date, even if it falls on a holiday or weekend. 049 * 050 * @author Benoit Xhenseval 051 * 052 */ 053public class LocalDateCalculator extends AbstractDateCalculator<LocalDate> { 054 055 private Jdk8WorkingWeek workingWeek = Jdk8WorkingWeek.DEFAULT; 056 057 public LocalDateCalculator() { 058 this(null, null, new DefaultHolidayCalendar<>(Collections.emptySet()), null); 059 } 060 061 public LocalDateCalculator(final String name, final LocalDate startDate, final HolidayCalendar<LocalDate> holidayCalendar, 062 final HolidayHandler<LocalDate> holidayHandler) { 063 super(name, holidayCalendar, holidayHandler); 064 if (startDate != null) { 065 setStartDate(startDate); 066 } 067 } 068 069 /** 070 * Set the working week. 071 * @param week the JodaWorkingWeek 072 * @throws IllegalArgumentException if the week is not a JodaWorkingWeek. 073 */ 074 @Override 075 public DateCalculator<LocalDate> setWorkingWeek(final WorkingWeek week) { 076 if (week instanceof Jdk8WorkingWeek) { 077 workingWeek = (Jdk8WorkingWeek) week; 078 return this; 079 } 080 throw new IllegalArgumentException("Please give an instance of JodaWorkingWeek"); 081 } 082 083 /** 084 * is the date a non-working day according to the WorkingWeek? 085 */ 086 @Override 087 public boolean isWeekend(final LocalDate date) { 088 assert workingWeek != null; 089 return !workingWeek.isWorkingDay(date); 090 } 091 092 // ----------------------------------------------------------------------- 093 // 094 // ObjectLab, world leaders in the design and development of bespoke 095 // applications for the securities financing markets. 096 // www.ObjectLab.co.uk 097 // 098 // ----------------------------------------------------------------------- 099 100 @Override 101 public DateCalculator<LocalDate> moveByDays(final int days) { 102 setCurrentIncrement(days); 103 104 setCurrentBusinessDate(getCurrentBusinessDate().plusDays(days)); 105 106 if (getHolidayHandler() != null) { 107 setCurrentBusinessDate(getHolidayHandler().moveCurrentDate(this)); 108 } 109 110 return this; 111 } 112 113 @Override 114 public DateCalculator<LocalDate> moveByMonths(final int months) { 115 setCurrentIncrement(months); 116 117 setCurrentBusinessDate(getCurrentBusinessDate().plusMonths(months)); 118 119 if (getHolidayHandler() != null) { 120 setCurrentBusinessDate(getHolidayHandler().moveCurrentDate(this)); 121 } 122 123 return this; 124 } 125 126 @Override 127 protected DateCalculator<LocalDate> createNewCalculator(final String name, final LocalDate startDate, final HolidayCalendar<LocalDate> holidays, 128 final HolidayHandler<LocalDate> handler) { 129 return new LocalDateCalculator(name, startDate, holidays, handler); 130 } 131 132 @Override 133 protected LocalDate getToday() { 134 return LocalDate.now(); 135 } 136 137 @Override 138 protected LocalDate compareDate(final LocalDate date1, final LocalDate date2, final boolean returnEarliest) { 139 if (date1 == null || date2 == null) { 140 return null; 141 } 142 if (returnEarliest) { 143 return date1.isAfter(date2) ? date2 : date1; 144 } else { 145 return date2.isAfter(date1) ? date2 : date1; 146 } 147 } 148 149 @Override 150 protected void checkBoundary(final LocalDate date) { 151 final LocalDate early = getHolidayCalendar().getEarlyBoundary(); 152 if (early != null && early.isAfter(date)) { 153 throw new IndexOutOfBoundsException(date + " is before the early boundary " + early); 154 } 155 156 final LocalDate late = getHolidayCalendar().getLateBoundary(); 157 if (late != null && late.isBefore(date)) { 158 throw new IndexOutOfBoundsException(date + " is after the late boundary " + late); 159 } 160 } 161 162 @Override 163 protected LocalDate clone(final LocalDate date) { 164 return date; 165 } 166 167 @Override 168 public int getNumberOfBusinessDaysBetween(final LocalDate d1, final LocalDate d2) { 169 if (d1 == null || d2 == null) { 170 return 0; 171 } 172 final boolean d1B4d2 = !d1.isAfter(d2); 173 LocalDate start = d1B4d2 ? d1 : d2; 174 LocalDate end = d1B4d2 ? d2 : d1; 175 if (getHolidayHandler() != null) { 176 start = getHolidayHandler().adjustDate(start, 1, this); 177 } 178 179 int count = 0; 180 while (start.isBefore(end)) { 181 if (!isNonWorkingDay(start)) { 182 count++; 183 } 184 start = start.plusDays(1); 185 } 186 return d1B4d2 ? count : -count; 187 } 188} 189 190/* 191 * ObjectLab, http://www.objectlab.co.uk/open is sponsoring the ObjectLab Kit. 192 * 193 * Based in London, we are world leaders in the design and development 194 * of bespoke applications for the securities financing markets. 195 * 196 * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a> 197 * ___ _ _ _ _ _ 198 * / _ \| |__ (_) ___ ___| |_| | __ _| |__ 199 * | | | | '_ \| |/ _ \/ __| __| | / _` | '_ \ 200 * | |_| | |_) | | __/ (__| |_| |__| (_| | |_) | 201 * \___/|_.__// |\___|\___|\__|_____\__,_|_.__/ 202 * |__/ 203 * 204 * www.ObjectLab.co.uk 205 */