/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.basics.date;
import java.io.Serializable;
import java.time.LocalDate;
import com.google.common.base.Splitter;
import com.opengamma.collect.ArgChecker;
import com.opengamma.collect.named.ExtendedEnum;
/**
* Constants and implementations for standard holiday calendars.
* <p>
* The purpose of each holiday calendar is to define whether a date is a holiday or a business day.
* The is of use in many calculations.
* <p>
* The holiday calendar data provided here has been identified through direct research and is not
* derived from a vendor of holiday calendar data.
* This data may or may not be sufficient for your production needs.
* To change the implementation, see {@code HolidayCalendar.properties}.
*/
public final class HolidayCalendars {
// constants are indirected via ENUM_LOOKUP to allow them to be replaced by config
/**
* The extended enum lookup from name to instance.
*/
static final ExtendedEnum<HolidayCalendar> ENUM_LOOKUP = ExtendedEnum.of(HolidayCalendar.class);
/**
* An instance declaring no holidays and no weekends.
* <p>
* This calendar has the effect of making every day a business day.
* It is often used to indicate that a holiday calendar does not apply.
*/
public static final HolidayCalendar NO_HOLIDAYS = HolidayCalendar.of(StandardHolidayCalendars.NO_HOLIDAYS.getName());
/**
* An instance declaring all days as business days except Saturday/Sunday weekends.
* <p>
* This calendar is mostly useful in testing scenarios.
* Note that not all countries use Saturday and Sunday weekends.
*/
public static final HolidayCalendar SAT_SUN = HolidayCalendar.of(StandardHolidayCalendars.SAT_SUN.getName());
/**
* An instance declaring all days as business days except Friday/Saturday weekends.
* <p>
* This calendar is mostly useful in testing scenarios.
*/
public static final HolidayCalendar FRI_SAT = HolidayCalendar.of(StandardHolidayCalendars.FRI_SAT.getName());
/**
* An instance declaring all days as business days except Thursday/Friday weekends.
* <p>
* This calendar is mostly useful in testing scenarios.
*/
public static final HolidayCalendar THU_FRI = HolidayCalendar.of(StandardHolidayCalendars.THU_FRI.getName());
/**
* The holiday calendar for London, United Kingdom, with code 'GBLO'.
* <p>
* This constant provides the calendar for London bank holidays.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
*/
public static final HolidayCalendar GBLO = HolidayCalendar.of(GlobalHolidayCalendars.GBLO.getName());
/**
* The holiday calendar for Paris, France, with code 'FRPA'.
* <p>
* This constant provides the calendar for Paris public holidays.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future and past dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
*/
public static final HolidayCalendar FRPA = HolidayCalendar.of(GlobalHolidayCalendars.FRPA.getName());
/**
* The holiday calendar for Zurich, Switzerland, with code 'EUTA'.
* <p>
* This constant provides the calendar for Zurich public holidays.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future and past dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
*/
public static final HolidayCalendar CHZU = HolidayCalendar.of(GlobalHolidayCalendars.CHZU.getName());
/**
* The holiday calendar for the European Union TARGET system, with code 'EUTA'.
* <p>
* This constant provides the calendar for the TARGET interbank payment system holidays.
* <p>
* The default implementation is based on original research and covers 1997 to 2099.
* Future dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
* <p>
* Referenced by the 2006 ISDA definitions 1.8.
*/
public static final HolidayCalendar EUTA = HolidayCalendar.of(GlobalHolidayCalendars.EUTA.getName());
/**
* The holiday calendar for United States Government Securities, with code 'USGS'.
* <p>
* This constant provides the calendar for United States Government Securities as per SIFMA.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future and past dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
* <p>
* Referenced by the 2006 ISDA definitions 1.11.
*/
public static final HolidayCalendar USGS = HolidayCalendar.of(GlobalHolidayCalendars.USGS.getName());
/**
* The holiday calendar for New York, United States, with code 'USNY'.
* <p>
* This constant provides the calendar for New York holidays.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future and past dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
*/
public static final HolidayCalendar USNY = HolidayCalendar.of(GlobalHolidayCalendars.USNY.getName());
/**
* The holiday calendar for the Federal Reserve Bank of New York, with code 'NYFD'.
* <p>
* This constant provides the calendar for the Federal Reserve Bank of New York holidays.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future and past dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
* <p>
* Referenced by the 2006 ISDA definitions 1.9.
*/
public static final HolidayCalendar NYFD = HolidayCalendar.of(GlobalHolidayCalendars.NYFD.getName());
/**
* The holiday calendar for the New York Stock Exchange, with code 'NYSE'.
* <p>
* This constant provides the calendar for the New York Stock Exchange.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future and past dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
* <p>
* Referenced by the 2006 ISDA definitions 1.10.
*/
public static final HolidayCalendar NYSE = HolidayCalendar.of(GlobalHolidayCalendars.NYSE.getName());
/**
* The holiday calendar for Tokyo, Japan, with code 'JPTO'.
* <p>
* This constant provides the calendar for Tokyo bank holidays.
* <p>
* The default implementation is based on original research and covers 1950 to 2099.
* Future and past dates are an extrapolations of the latest known rules.
* To change the implementation, see {@code HolidayCalendar.properties}.
*/
public static final HolidayCalendar JPTO = HolidayCalendar.of(GlobalHolidayCalendars.JPTO.getName());
//-------------------------------------------------------------------------
/**
* Obtains a {@code HolidayCalendar} from a unique name.
*
* @param uniqueName the unique name of the calendar
* @return the holiday calendar
*/
static HolidayCalendar of(String uniqueName) {
ArgChecker.notNull(uniqueName, "uniqueName");
if (uniqueName.contains("+")) {
return Splitter.on('+').splitToList(uniqueName).stream()
.map(HolidayCalendars::of)
.reduce(NO_HOLIDAYS, HolidayCalendar::combineWith);
}
return ENUM_LOOKUP.lookup(uniqueName);
}
//-------------------------------------------------------------------------
/**
* Restricted constructor.
*/
private HolidayCalendars() {
}
//-------------------------------------------------------------------------
/**
* Implementation of the combined holiday calendar.
*/
static final class Combined implements HolidayCalendar, Serializable {
// Serialization version
private static final long serialVersionUID = 1L;
// calendar 1
private final HolidayCalendar calendar1;
// calendar 2
private final HolidayCalendar calendar2;
// name
private final String name;
private Object readResolve() {
return new Combined(calendar1, calendar2);
}
// create
Combined(HolidayCalendar calendar1, HolidayCalendar calendar2) {
this.calendar1 = ArgChecker.notNull(calendar1, "calendar1");
this.calendar2 = ArgChecker.notNull(calendar2, "calendar2");
this.name = calendar1.getName() + "+" + calendar2.getName();
}
@Override
public boolean isHoliday(LocalDate date) {
return calendar1.isHoliday(date) || calendar2.isHoliday(date);
}
@Override
public String getName() {
return name;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Combined) {
return ((Combined) obj).name.equals(name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public String toString() {
return name;
}
}
}