Skip to content

Commit

Permalink
Update holiday calendars (#1961)
Browse files Browse the repository at this point in the history
Pickup changes in JPTO, DEFR, FRPA, HUBU, PLWA
  • Loading branch information
jodastephen authored Apr 30, 2019
1 parent 24c520c commit d1849ba
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@
import static java.time.temporal.TemporalAdjusters.lastInMonth;
import static java.time.temporal.TemporalAdjusters.nextOrSame;
import static java.time.temporal.TemporalAdjusters.previous;
import static java.util.stream.Collectors.toSet;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.MonthDay;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashSet;
Expand Down Expand Up @@ -183,7 +181,7 @@ static ImmutableHolidayCalendar generateLondon() {
// New Years Eve is holiday for cash markets and derivatives in 2015
// https://www.euronext.com/en/holidays-and-hours
// https://www.euronext.com/en/trading/nyse-euronext-trading-calendar/archives
// evidence suggests that Monday is holiday when Tuesday is, and Friday is holiday when Thursday is
// some sources have Monday is holiday when Tuesday is, and Friday is holiday when Thursday is (not applying this)
static ImmutableHolidayCalendar generateParis() {
List<LocalDate> holidays = new ArrayList<>(2000);
for (int year = 1950; year <= 2099; year++) {
Expand All @@ -204,7 +202,6 @@ static ImmutableHolidayCalendar generateParis() {
holidays.add(date(year, 12, 26)); // saint stephen
}
holidays.add(date(1999, 12, 31)); // millennium
applyBridging(holidays);
removeSatSun(holidays);
return ImmutableHolidayCalendar.of(HolidayCalendarIds.FRPA, holidays, SATURDAY, SUNDAY);
}
Expand All @@ -214,6 +211,7 @@ static ImmutableHolidayCalendar generateParis() {
// data sources
// https://www.feiertagskalender.ch/index.php?geo=3122&klasse=3&jahr=2017&hl=en
// http://jollyday.sourceforge.net/data/de.html
// http://en.boerse-frankfurt.de/basics-marketplaces-tradingcalendar2019
static ImmutableHolidayCalendar generateFrankfurt() {
List<LocalDate> holidays = new ArrayList<>(2000);
for (int year = 1950; year <= 2099; year++) {
Expand All @@ -231,6 +229,7 @@ static ImmutableHolidayCalendar generateFrankfurt() {
// Wed before the Sunday that is 2 weeks before first advent, which is 4th Sunday before Christmas
holidays.add(date(year, 12, 25).with(previous(SUNDAY)).minusWeeks(6).minusDays(4)); // repentance
}
holidays.add(date(year, 12, 24)); // christmas eve
holidays.add(date(year, 12, 25)); // christmas day
holidays.add(date(year, 12, 26)); // saint stephen
holidays.add(date(year, 12, 31)); // new year
Expand Down Expand Up @@ -494,6 +493,7 @@ static ImmutableHolidayCalendar generateNewYorkStockExchange() {
// http://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html (law)
// http://www.nao.ac.jp/faq/a0301.html (equinox)
// http://eco.mtk.nao.ac.jp/koyomi/faq/holiday.html.en
// https://www.jpx.co.jp/english/announce/market-holidays.html
static ImmutableHolidayCalendar generateTokyo() {
List<LocalDate> holidays = new ArrayList<>(2000);
for (int year = 1950; year <= 2099; year++) {
Expand Down Expand Up @@ -545,7 +545,7 @@ static ImmutableHolidayCalendar generateTokyo() {
}
// mountain
if (year >= 2016) {
holidays.add(bumpSunToMon(date(year, 8, 11)));
holidays.add(bumpSunAndTueToMon(date(year, 8, 11)));
}
// aged
if (year >= 2003) {
Expand All @@ -571,17 +571,24 @@ static ImmutableHolidayCalendar generateTokyo() {
holidays.add(bumpSunToMon(date(year, 11, 3)));
// labor (from 1948)
holidays.add(bumpSunToMon(date(year, 11, 23)));
// emperor (current emporer)
if (year >= 1990) {
// emperor (current emporer birthday)
if (year >= 1990 && year < 2019) {
holidays.add(bumpSunToMon(date(year, 12, 23)));
}
if (year >= 2020) {
holidays.add(bumpSunToMon(date(year, 2, 23)));
}
// new years eve - bank of Japan, but not national holiday
holidays.add(bumpSunToMon(date(year, 12, 31)));
}
holidays.add(date(1959, 4, 10)); // marriage akihito
holidays.add(date(1989, 2, 24)); // funeral showa
holidays.add(date(1990, 11, 12)); // enthrone akihito
holidays.add(date(1993, 6, 9)); // marriage naruhito
holidays.add(date(2019, 4, 30)); // abdication
holidays.add(date(2019, 5, 1)); // accession
holidays.add(date(2019, 5, 2)); // accession
holidays.add(date(2019, 10, 22)); // enthronement
removeSatSun(holidays);
return ImmutableHolidayCalendar.of(HolidayCalendarIds.JPTO, holidays, SATURDAY, SUNDAY);
}
Expand Down Expand Up @@ -820,6 +827,9 @@ private static void newZealand(List<LocalDate> holidays, int year) {
// http://isap.sejm.gov.pl/DetailsServlet?id=WDU19510040028 and linked pages
// https://www.gpw.pl/dni_bez_sesji_en
// http://jollyday.sourceforge.net/data/pl.html
// https://www.gpw.pl/session-details
// https://www.gpw.pl/news?cmn_id=107609&title=No+exchange+trading+session+on+12+November+2018
// https://www.gpw.pl/news?cmn_id=107794&title=December+24%2C+2018+-+Closing+day
static ImmutableHolidayCalendar generateWarsaw() {
// holiday law dates from 1951, but don't know situation before then, so ignore 1951 date
List<LocalDate> holidays = new ArrayList<>(2000);
Expand All @@ -830,8 +840,6 @@ static ImmutableHolidayCalendar generateWarsaw() {
if (year < 1961 || year >= 2011) {
holidays.add(date(year, 1, 6));
}
// good friday
holidays.add(easter(year).minusDays(2));
// easter monday
holidays.add(easter(year).plusDays(1));
// state
Expand Down Expand Up @@ -1010,6 +1018,7 @@ static ImmutableHolidayCalendar generateJohannesburg() {
// https://englishhungary.wordpress.com/2012/01/15/bridge-days/
// http://www.ucmsgroup.hu/newsletter/public-holiday-and-related-work-schedule-changes-in-2015/
// http://www.ucmsgroup.hu/newsletter/public-holiday-and-related-work-schedule-changes-in-2014/
// https://www.bse.hu/Products-and-Services/Trading-information/tranding-calendar-2019
static ImmutableHolidayCalendar generateBudapest() {
List<LocalDate> holidays = new ArrayList<>(2000);
Set<LocalDate> workDays = new HashSet<>(500);
Expand All @@ -1035,6 +1044,7 @@ static ImmutableHolidayCalendar generateBudapest() {
// all saints day
addDateWithHungarianBridging(date(year, 11, 1), -3, 1, holidays, workDays);
// christmas
holidays.add(date(year, 12, 24));
holidays.add(date(year, 12, 25));
holidays.add(date(year, 12, 26));
if (date(year, 12, 25).getDayOfWeek() == TUESDAY) {
Expand Down Expand Up @@ -1240,6 +1250,17 @@ private static LocalDate bumpSunToMon(LocalDate date) {
return date;
}

// bump Sunday & Tuesday to the Monday
private static LocalDate bumpSunAndTueToMon(LocalDate date) {
if (date.getDayOfWeek() == SUNDAY) {
return date.plusDays(1);
}
if (date.getDayOfWeek() == TUESDAY) {
return date.minusDays(1);
}
return date;
}

// bump to Saturday to Friday and Sunday to Monday
private static LocalDate bumpToFriOrMon(LocalDate date) {
if (date.getDayOfWeek() == SATURDAY) {
Expand Down Expand Up @@ -1296,22 +1317,6 @@ private static void removeSatSun(List<LocalDate> holidays) {
holidays.removeIf(date -> date.getDayOfWeek() == SATURDAY || date.getDayOfWeek() == SUNDAY);
}

// apply bridging (Mon/Fri are holidays if Tue/Thu are)
private static void applyBridging(List<LocalDate> holidays) {
Set<LocalDate> additional1 = holidays.stream()
.filter(date -> date.getDayOfWeek() == TUESDAY &&
!MonthDay.from(date).equals(MonthDay.of(1, 1)))
.map(date -> date.minusDays(1))
.collect(toSet());
Set<LocalDate> additional2 = holidays.stream()
.filter(date -> date.getDayOfWeek() == THURSDAY &&
!MonthDay.from(date).equals(MonthDay.of(12, 26)))
.map(date -> date.plusDays(1))
.collect(toSet());
holidays.addAll(additional1);
holidays.addAll(additional2);
}

// calculate easter day by Delambre
static LocalDate easter(int year) {
int a = year % 19;
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -289,29 +289,29 @@ public void test_gblo(int year, List<LocalDate> holidays) {
public static Object[][] data_frpa() {
return new Object[][] {
// dates not shifted if fall on a weekend
{2003, mds(2003, md(1, 1), md(4, 18), md(4, 21), md(5, 1), md(5, 2), md(5, 8), md(5, 9), md(5, 29), md(5, 30),
md(6, 9), md(7, 14), md(8, 15), md(11, 1), md(11, 10), md(11, 11), md(12, 25), md(12, 26))},
{2004, mds(2004, md(1, 1), md(1, 2), md(4, 9), md(4, 12), md(5, 1), md(5, 8), md(5, 20), md(5, 21), md(5, 31),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(11, 12), md(12, 25), md(12, 26))},
{2005, mds(2005, md(1, 1), md(3, 25), md(3, 28), md(5, 1), md(5, 5), md(5, 6), md(5, 8),
md(7, 14), md(7, 15), md(8, 15), md(10, 31), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2006, mds(2006, md(1, 1), md(4, 14), md(4, 17), md(5, 1), md(5, 8), md(5, 25), md(5, 26),
md(7, 14), md(8, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2007, mds(2007, md(1, 1), md(4, 6), md(4, 9), md(4, 30), md(5, 1), md(5, 7), md(5, 8), md(5, 17), md(5, 18),
md(7, 14), md(8, 15), md(11, 1), md(11, 2), md(11, 11), md(12, 24), md(12, 25), md(12, 26))},
{2008, mds(2008, md(1, 1), md(3, 21), md(3, 24), md(5, 1), md(5, 2), md(5, 8), md(5, 9), md(5, 12), md(5, 24),
md(7, 14), md(8, 15), md(11, 1), md(11, 10), md(11, 11), md(12, 25), md(12, 26))},

{2012, mds(2012, md(1, 1), md(4, 6), md(4, 9), md(4, 30), md(5, 1), md(5, 7), md(5, 8), md(5, 17), md(5, 18),
md(5, 28), md(7, 14), md(8, 15), md(11, 1), md(11, 2), md(11, 10), md(11, 11), md(12, 24), md(12, 25), md(12, 26))},
{2013, mds(2013, md(1, 1), md(3, 29), md(4, 1), md(5, 1), md(5, 8), md(5, 9), md(5, 10), md(5, 20),
md(7, 14), md(8, 15), md(8, 16), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2014, mds(2014, md(1, 1), md(4, 18), md(4, 21), md(5, 1), md(5, 2), md(5, 8), md(5, 9), md(5, 29), md(5, 30),
md(6, 9), md(7, 14), md(8, 15), md(11, 1), md(11, 10), md(11, 11), md(12, 25), md(12, 26))},
{2015, mds(2015, md(1, 1), md(1, 2), md(4, 3), md(4, 6), md(5, 1), md(5, 8), md(5, 14), md(5, 15), md(5, 25),
md(7, 13), md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2016, mds(2016, md(1, 1), md(3, 25), md(3, 28), md(5, 1), md(5, 5), md(5, 6), md(5, 8), md(5, 16),
md(7, 14), md(7, 15), md(8, 15), md(10, 31), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2003, mds(2003, md(1, 1), md(4, 18), md(4, 21), md(5, 1), md(5, 8), md(5, 29),
md(6, 9), md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2004, mds(2004, md(1, 1), md(4, 9), md(4, 12), md(5, 1), md(5, 8), md(5, 20), md(5, 31),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2005, mds(2005, md(1, 1), md(3, 25), md(3, 28), md(5, 1), md(5, 5), md(5, 8),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2006, mds(2006, md(1, 1), md(4, 14), md(4, 17), md(5, 1), md(5, 8), md(5, 25),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2007, mds(2007, md(1, 1), md(4, 6), md(4, 9), md(5, 1), md(5, 8), md(5, 17),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2008, mds(2008, md(1, 1), md(3, 21), md(3, 24), md(5, 1), md(5, 8), md(5, 12), md(5, 24),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},

{2012, mds(2012, md(1, 1), md(4, 6), md(4, 9), md(5, 1), md(5, 8), md(5, 17),
md(5, 28), md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2013, mds(2013, md(1, 1), md(3, 29), md(4, 1), md(5, 1), md(5, 8), md(5, 9), md(5, 20),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2014, mds(2014, md(1, 1), md(4, 18), md(4, 21), md(5, 1), md(5, 8), md(5, 29),
md(6, 9), md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2015, mds(2015, md(1, 1), md(4, 3), md(4, 6), md(5, 1), md(5, 8), md(5, 14), md(5, 25),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
{2016, mds(2016, md(1, 1), md(3, 25), md(3, 28), md(5, 1), md(5, 5), md(5, 8), md(5, 16),
md(7, 14), md(8, 15), md(11, 1), md(11, 11), md(12, 25), md(12, 26))},
};
}

Expand All @@ -334,9 +334,9 @@ public static Object[][] data_defr() {
return new Object[][] {
// dates not shifted if fall on a weekend
{2014, mds(2014, md(1, 1), md(4, 18), md(4, 21), md(5, 1), md(5, 29), md(6, 9), md(6, 19),
md(10, 3), md(12, 25), md(12, 26), md(12, 31))},
md(10, 3), md(12, 24), md(12, 25), md(12, 26), md(12, 31))},
{2015, mds(2015, md(1, 1), md(4, 3), md(4, 6), md(5, 1), md(5, 14), md(5, 25), md(6, 4),
md(10, 3), md(12, 25), md(12, 26), md(12, 31))},
md(10, 3), md(12, 24), md(12, 25), md(12, 26), md(12, 31))},
{2016, mds(2016, md(1, 1), md(3, 25), md(3, 28), md(5, 1), md(5, 5), md(5, 16), md(5, 26),
md(10, 3), md(12, 25), md(12, 26), md(12, 31))},
{2017, mds(2017, md(1, 1), md(4, 14), md(4, 17), md(5, 1), md(5, 25), md(6, 5), md(6, 15),
Expand Down Expand Up @@ -1066,17 +1066,17 @@ public void test_nzbd(int year, List<LocalDate> holidays) {
public static Object[][] data_plwa() {
// based on government law data and stock exchange holidays
return new Object[][] {
{2013, mds(2013, md(1, 1), md(3, 29), md(4, 1),
{2013, mds(2013, md(1, 1), md(4, 1),
md(5, 1), md(5, 3), md(5, 30), md(8, 15), md(11, 1), md(11, 11), md(12, 24), md(12, 25), md(12, 26))},
{2014, mds(2014, md(1, 1), md(1, 6), md(4, 18), md(4, 21),
{2014, mds(2014, md(1, 1), md(1, 6), md(4, 21),
md(5, 1), md(6, 19), md(8, 15), md(11, 11), md(12, 24), md(12, 25), md(12, 26))},
{2015, mds(2015, md(1, 1), md(1, 6), md(4, 3), md(4, 6),
{2015, mds(2015, md(1, 1), md(1, 6), md(4, 6),
md(5, 1), md(6, 4), md(11, 11), md(12, 24), md(12, 25), md(12, 31))},
{2016, mds(2016, md(1, 1), md(1, 6), md(3, 25), md(3, 28),
{2016, mds(2016, md(1, 1), md(1, 6), md(3, 28),
md(5, 3), md(5, 26), md(8, 15), md(11, 1), md(11, 11), md(12, 26))},
{2017, mds(2017, md(1, 6), md(4, 14), md(4, 17),
{2017, mds(2017, md(1, 6), md(4, 17),
md(5, 1), md(5, 3), md(6, 15), md(8, 15), md(11, 1), md(12, 25), md(12, 26))},
{2018, mds(2018, md(1,1), md(1,6), md(3,30), md(4,1), md(4,2), md(5,1), md(5,3),
{2018, mds(2018, md(1, 1), md(1, 6), md(4, 1), md(4, 2), md(5, 1), md(5, 3),
md(5,20), md(5,31), md(8,15), md(11,1), md(11,11), md(11,12), md(12,24), md(12,25), md(12,26), md(12,31))}
};
}
Expand Down

0 comments on commit d1849ba

Please sign in to comment.