|
| 1 | +/* |
| 2 | + * |
| 3 | + * Copyright 2012 Netflix, Inc. |
| 4 | + * |
| 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | + * you may not use this file except in compliance with the License. |
| 7 | + * You may obtain a copy of the License at |
| 8 | + * |
| 9 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | + * |
| 11 | + * Unless required by applicable law or agreed to in writing, software |
| 12 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | + * See the License for the specific language governing permissions and |
| 15 | + * limitations under the License. |
| 16 | + * |
| 17 | + */ |
| 18 | +package com.netflix.simianarmy.basic.calendars; |
| 19 | + |
| 20 | +import com.netflix.simianarmy.MonkeyConfiguration; |
| 21 | +import com.netflix.simianarmy.basic.BasicCalendar; |
| 22 | + |
| 23 | +import java.util.Arrays; |
| 24 | +import java.util.Calendar; |
| 25 | +import java.util.Collection; |
| 26 | + |
| 27 | +// CHECKSTYLE IGNORE MagicNumberCheck |
| 28 | +/** |
| 29 | + * The Class BavarianCalendar. |
| 30 | + */ |
| 31 | +public class BavarianCalendar extends BasicCalendar |
| 32 | +{ |
| 33 | + /** |
| 34 | + * Instantiates a new basic calendar. |
| 35 | + * |
| 36 | + * @param cfg the monkey configuration |
| 37 | + */ |
| 38 | + public BavarianCalendar(MonkeyConfiguration cfg) |
| 39 | + { |
| 40 | + super(cfg); |
| 41 | + } |
| 42 | + |
| 43 | + /** {@inheritDoc} */ |
| 44 | + @Override |
| 45 | + protected void loadHolidays(int year) { |
| 46 | + holidays.clear(); |
| 47 | + |
| 48 | + // these aren't all strictly holidays, but days when engineers will likely |
| 49 | + // not be in the office to respond to rampaging monkeys |
| 50 | + |
| 51 | + // first of all, we need easter sunday doy, |
| 52 | + // because ome other holidays calculated from it |
| 53 | + int easter = westernEasterDayOfYear(year); |
| 54 | + |
| 55 | + // new year |
| 56 | + holidays.addAll(getHolidayWithBridgeDays(year, dayOfYear(year, Calendar.JANUARY, 1))); |
| 57 | + |
| 58 | + // epiphanie |
| 59 | + holidays.addAll(getHolidayWithBridgeDays(year, dayOfYear(year, Calendar.JANUARY, 6))); |
| 60 | + |
| 61 | + // good friday, always friday, don't need to check if it's bridge day |
| 62 | + holidays.add(easter - 2); |
| 63 | + |
| 64 | + // easter monday, always monday, don't need to check if it's bridge day |
| 65 | + holidays.add(easter + 1); |
| 66 | + |
| 67 | + // labor day |
| 68 | + holidays.addAll(getHolidayWithBridgeDays(year, dayOfYear(year, Calendar.MAY, 1))); |
| 69 | + |
| 70 | + // ascension day |
| 71 | + holidays.addAll(getHolidayWithBridgeDays(year, easter + 39)); |
| 72 | + |
| 73 | + // whit monday, always monday, don't need to check if it's bridge day |
| 74 | + holidays.add(easter + 50); |
| 75 | + |
| 76 | + // corpus christi |
| 77 | + holidays.add(westernEasterDayOfYear(year) + 60); |
| 78 | + |
| 79 | + // assumption day |
| 80 | + holidays.addAll(getHolidayWithBridgeDays(year, dayOfYear(year, Calendar.AUGUST, 15))); |
| 81 | + |
| 82 | + // german unity day |
| 83 | + holidays.addAll(getHolidayWithBridgeDays(year, dayOfYear(year, Calendar.OCTOBER, 3))); |
| 84 | + |
| 85 | + // all saints |
| 86 | + holidays.addAll(getHolidayWithBridgeDays(year, dayOfYear(year, Calendar.NOVEMBER, 1))); |
| 87 | + |
| 88 | + // monkey goes on christmas vacations between christmas and new year! |
| 89 | + holidays.addAll(getHolidayWithBridgeDays(year, dayOfYear(year, Calendar.DECEMBER, 24))); |
| 90 | + holidays.add(dayOfYear(year, Calendar.DECEMBER, 25)); |
| 91 | + holidays.add(dayOfYear(year, Calendar.DECEMBER, 26)); |
| 92 | + holidays.add(dayOfYear(year, Calendar.DECEMBER, 27)); |
| 93 | + holidays.add(dayOfYear(year, Calendar.DECEMBER, 28)); |
| 94 | + holidays.add(dayOfYear(year, Calendar.DECEMBER, 29)); |
| 95 | + holidays.add(dayOfYear(year, Calendar.DECEMBER, 30)); |
| 96 | + holidays.add(dayOfYear(year, Calendar.DECEMBER, 31)); |
| 97 | + |
| 98 | + // mark the holiday set with the year, so on Jan 1 it will automatically |
| 99 | + // recalculate the holidays for next year |
| 100 | + holidays.add(year); |
| 101 | + } |
| 102 | + |
| 103 | + /** |
| 104 | + * Returns collection of holidays, including Monday or Friday |
| 105 | + * if given holiday is Thuesday or Thursday. |
| 106 | + * |
| 107 | + * The behaviour to take Monday as day off if official holiday is Thuesday |
| 108 | + * and to take Friday as day off if official holiday is Thursday |
| 109 | + * is specific to [at least] Germany. |
| 110 | + * We call it, literally, "bridge day". |
| 111 | + * |
| 112 | + * @param dayOfYear holiday day of year |
| 113 | + */ |
| 114 | + private Collection<Integer> getHolidayWithBridgeDays(int year, int dayOfYear) { |
| 115 | + Calendar holiday = now(); |
| 116 | + holiday.set(Calendar.YEAR, year); |
| 117 | + holiday.set(Calendar.DAY_OF_YEAR, dayOfYear); |
| 118 | + int dow = holiday.get(Calendar.DAY_OF_WEEK); |
| 119 | + int mon = holiday.get(Calendar.MONTH); |
| 120 | + int dom = holiday.get(Calendar.DAY_OF_MONTH); |
| 121 | + |
| 122 | + // We don't want to include Monday if Thuesday is January 1. |
| 123 | + if (dow == Calendar.TUESDAY && dayOfYear != 1) |
| 124 | + return Arrays.asList(dayOfYear, dayOfYear - 1); |
| 125 | + |
| 126 | + // We don't want to include Friday if Thursday is December 31. |
| 127 | + if (dow == Calendar.THURSDAY && (mon != Calendar.DECEMBER || dom != 31)) |
| 128 | + return Arrays.asList(dayOfYear, dayOfYear + 1); |
| 129 | + |
| 130 | + return Arrays.asList(dayOfYear); |
| 131 | + } |
| 132 | + |
| 133 | + /** |
| 134 | + * Western easter sunday in year. |
| 135 | + * |
| 136 | + * @param year |
| 137 | + * the year |
| 138 | + * @return the day of the year of western easter sunday |
| 139 | + */ |
| 140 | + protected int westernEasterDayOfYear(int year) { |
| 141 | + int a = year % 19, |
| 142 | + b = year / 100, |
| 143 | + c = year % 100, |
| 144 | + d = b / 4, |
| 145 | + e = b % 4, |
| 146 | + g = (8 * b + 13) / 25, |
| 147 | + h = (19 * a + b - d - g + 15) % 30, |
| 148 | + j = c / 4, |
| 149 | + k = c % 4, |
| 150 | + m = (a + 11 * h) / 319, |
| 151 | + r = (2 * e + 2 * j - k - h + m + 32) % 7; |
| 152 | + int oneBasedMonth = (h - m + r + 90) / 25; |
| 153 | + int dayOfYear = (h - m + r + oneBasedMonth + 19) % 32; |
| 154 | + return dayOfYear(year, oneBasedMonth - 1, dayOfYear); |
| 155 | + } |
| 156 | + |
| 157 | +} |
0 commit comments