2007-01-xx: version 1.1.0 is out and contains a couple of changes, a new HolidayHandler and the ability to define a valid range for the holiday (and if the calculation is beyond that range, an exception is thrown). This is done via HolidayCalendar which should replace the simple Set<E> for holidays. More info on the changes here.
ObjectLab Kit came out of our frustration to have to re-do the same kind of code over and over each time we
joined a new company and Bank. Most banks will require basic Date calculation, we did spot another open source
project for this but their licence forbids most financial institution from using it. This one is released under
the business-friendly Apache 2.0 license.
![]()
The initial release provides 2 implementations for Date calculations, both depend on the classes in datecalc-common. So, you need to include:
the datecalc-jdk.jar has no dependencies other than JDK 1.5+. datecalc-joda.jar is based on the powerful JODA-Time library (we recommend it!)
Apart from the very basic "add days" features, most business have to deal with Holidays and what to do when a calculated day falls on a holiday. This library does not attempt to create or guess the holidays, we all know that some bank holidays can be decided at a moment's notice in some markets. All financial institutions or big business will have their own official list of 'holidays' anyway.
Furthermore, "weekends" also need to be handled and some market have a different week to the conventional Monday -> Friday, our library provides you with full flexibility to design a Working Week.
As such a Non-working Day can be a holiday or a 'weekend'.
At the moment, we support the following 6 algorithms:
See this page for some examples.
We are using yDoc to generate a 'javadoc-like' documentation per module with the added twist of UML diagrams:
The main interfaces are:
Here are the examples of how to get a DateCalculator "forward" for the "UK" holidays (if you have registered the holidays). The WorkingWeek is Mon-Fri by default.
2 implementations for Pure JDK have been released
DateCalculator<Calendar> calc = CalendarKitCalculatorsFactory.getDefaultInstance().getDateCalculator("UK", HolidayHandlerType.FORWARD);
PeriodCountCalculator<Calendar> calc = CalendarKitCalculatorsFactory.getDefaultInstance().getPeriodCountCalculator();
IMMDateCalculator<Calendar> calc = CalendarKitCalculatorsFactory.getDefaultInstance().getIMMDateCalculator();
DateCalculator<Date> calc = DateKitCalculatorsFactory.getDefaultInstance().getDateCalculator("UK", HolidayHandlerType.FORWARD);
PeriodCountCalculator<Date> calc = DateKitCalculatorsFactory.getDefaultInstance().getPeriodCountCalculator();
IMMDateCalculator<Date> calc = DateKitCalculatorsFactory.getDefaultInstance().getIMMDateCalculator();
2 implementations for Joda have been released
DateCalculator<LocalDate> calc = LocalDateKitCalculatorsFactory.getDefaultInstance().getDateCalculator("UK", HolidayHandlerType.FORWARD);
PeriodCountCalculator<LocalDate> calc = LocalDateKitCalculatorsFactory.getDefaultInstance().getPeriodCountCalculator();
IMMDateCalculator<LocalDate> calc = LocalDateKitCalculatorsFactory.getDefaultInstance().getIMMDateCalculator();
DateCalculator<YearMonthDay> calc = YearMonthDayKitCalculatorsFactory.getDefaultInstance().getDateCalculator("UK", HolidayHandlerType.FORWARD);
PeriodCountCalculator<YearMonthDay> calc = YearMonthDayKitCalculatorsFactory.getDefaultInstance().getPeriodCountCalculator();
IMMDateCalculator<YearMonthDay> calc = YearMonthDayKitCalculatorsFactory.getDefaultInstance().getIMMDateCalculator();
There are several steps
// create or get the Holidays
final Set<LocalDate> holidays = new HashSet<LocalDate>();
holidays.add(new LocalDate("2006-08-28"));
//... keep adding all holidays for 2006
// create the HolidayCalendar ASSUMING that the set covers 2006!
final HolidayCalendar<LocalDate> calendar = new DefaultHolidayCalendar<LocalDate>(holidays, new LocalDate("2006-01-01"), new LocalDate("2006-12-31"));
// register the holiday calendar (any calculator with name "UK" asked from now on will receive an IMMUTABLE reference to this calendar)
LocalDateKitCalculatorsFactory.getDefaultInstance().registerHolidays("UK", calendar);
// ask for a LocalDate calculator for "UK" (even if a new set of holidays is registered, this one calculator is not affected
DateCalculator<LocalDate> cal = LocalDateKitCalculatorsFactory.getDefaultInstance().getDateCalculator("UK", HolidayHandlerType.FORWARD);
cal.setStartDate(new LocalDate("2006-08-28")); // this also sets the current business date.
// the startDate stays 28 Aug 06 BUT the currentDate has moved,
// according to Forward handler to 29 Aug 2006.
LocalDate start = cal.getStartDate(); // 28 Aug 06
LocalDate current = cal.getCurrentBusinessDate(); // 29 Aug 06
LocalDate newCurrent = cal.moveByDays(4).getCurrentBusinessDate(); // 4 Sept 06 due to weekend!
// Example with Tenor, 1W with a 2 day spot lag
LocalDate date1WeekFromSpot = cal.moveByTenor(StandardTenor.T_1W, 2).getCurrentBusinessDate();
// create or get the Holidays
final Set<Calendar> holidays = new HashSet<Calendar>();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH,28);
calendar.set(Calendar.MONTH,Calendar.AUGUST);
calendar.set(Calendar.YEAR,2006);
holidays.add(calendar);
//... keep adding all holidays for 2006
// create the HolidayCalendar ASSUMING that the set covers 2006!
final HolidayCalendar<Calendar> calendar = new DefaultHolidayCalendar<Calendar>(holidays, new Calendar("2006-01-01"), new Calendar("2006-12-31"));
// register the holidays (any calculator with name "UK" asked from now on will receive an IMMUTABLE reference to this calendar
CalendarKitCalculatorsFactory.getDefaultInstance().registerHolidays("UK", calendar);
// ask for a LocalDate calculator for "UK" (even if a new set of holidays is registered, this one calculator is not affected
DateCalculator<Calendar> cal = LocalDateKitCalculatorsFactory.getDefaultInstance().getDateCalculator("UK", HolidayHandlerType.FORWARD);
Calendar initial = Calendar.getInstance();
initial.set(Calendar.DAY_OF_MONTH,28);
initial.set(Calendar.MONTH,Calendar.AUGUST);
initial.set(Calendar.YEAR,2006);
cal.setStartDate(initial); // this also sets the current business date.
// the startDate stays 28 Aug 06 BUT the currentDate has moved,
// according to Forward handler to 29 Aug 2006.
Calendar start = cal.getStartDate(); // 28 Aug 06
Calendar current = cal.getCurrentBusinessDate(); // 29 Aug 06
Calendar newCurrent = cal.moveByDays(4).getCurrentBusinessDate(); // 4 Sept 06 due to weekend!
// Example with Tenor, 1W with a 2 day spot lag
Calendar date1WeekFromSpot = cal.moveByTenor(StandardTenor.T_1W, 2).getCurrentBusinessDate();