1# -*- coding: utf-8 -*- 2 3# python-holidays 4# --------------- 5# A fast, efficient Python library for generating country, province and state 6# specific sets of holidays on the fly. It aims to make determining whether a 7# specific date is a holiday as fast and flexible as possible. 8# 9# Author: ryanss <ryanssdev@icloud.com> (c) 2014-2017 10# dr-prodigy <maurizio.montel@gmail.com> (c) 2017-2019 11# Website: https://github.com/dr-prodigy/python-holidays 12# License: MIT (see LICENSE file) 13 14from datetime import date, datetime, timedelta 15from dateutil.easter import easter, EASTER_ORTHODOX 16from dateutil.parser import parse 17from dateutil.relativedelta import relativedelta as rd 18from dateutil.relativedelta import MO, TU, WE, TH, FR, SA, SU 19import inspect 20import six 21import sys 22import warnings 23 24__version__ = '0.9.12' 25 26MON, TUE, WED, THU, FRI, SAT, SUN = range(7) 27WEEKEND = (SAT, SUN) 28 29JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, \ 30 NOV, DEC = range(1, 13) 31 32 33class HolidayBase(dict): 34 PROVINCES = [] 35 36 def __init__(self, years=[], expand=True, observed=True, 37 prov=None, state=None): 38 self.observed = observed 39 self.expand = expand 40 if isinstance(years, int): 41 years = [years, ] 42 self.years = set(years) 43 if not getattr(self, 'prov', False): 44 self.prov = prov 45 self.state = state 46 for year in list(self.years): 47 self._populate(year) 48 49 def __setattr__(self, key, value): 50 if key == 'observed' and len(self) > 0: 51 dict.__setattr__(self, key, value) 52 if value is True: 53 # Add (Observed) dates 54 years = list(self.years) 55 self.years = set() 56 self.clear() 57 for year in years: 58 self._populate(year) 59 else: 60 # Remove (Observed) dates 61 for k, v in list(self.items()): 62 if v.find("Observed") >= 0: 63 del self[k] 64 else: 65 return dict.__setattr__(self, key, value) 66 67 def __keytransform__(self, key): 68 if isinstance(key, datetime): 69 key = key.date() 70 elif isinstance(key, date): 71 key = key 72 elif isinstance(key, int) or isinstance(key, float): 73 key = datetime.utcfromtimestamp(key).date() 74 elif isinstance(key, six.string_types): 75 try: 76 key = parse(key).date() 77 except (ValueError, OverflowError): 78 raise ValueError("Cannot parse date from string '%s'" % key) 79 else: 80 raise TypeError("Cannot convert type '%s' to date." % type(key)) 81 82 if self.expand and key.year not in self.years: 83 self.years.add(key.year) 84 self._populate(key.year) 85 return key 86 87 def __contains__(self, key): 88 return dict.__contains__(self, self.__keytransform__(key)) 89 90 def __getitem__(self, key): 91 if isinstance(key, slice): 92 if not key.start or not key.stop: 93 raise ValueError("Both start and stop must be given.") 94 95 start = self.__keytransform__(key.start) 96 stop = self.__keytransform__(key.stop) 97 98 if key.step is None: 99 step = 1 100 elif isinstance(key.step, timedelta): 101 step = key.step.days 102 elif isinstance(key.step, int): 103 step = key.step 104 else: 105 raise TypeError( 106 "Cannot convert type '%s' to int." % type(key.step) 107 ) 108 109 if step == 0: 110 raise ValueError('Step value must not be zero.') 111 112 date_diff = stop - start 113 if date_diff.days < 0 <= step or date_diff.days >= 0 > step: 114 step *= -1 115 116 days_in_range = [] 117 for delta_days in range(0, date_diff.days, step): 118 day = start + timedelta(days=delta_days) 119 try: 120 dict.__getitem__( 121 self, 122 day 123 ) 124 days_in_range.append(day) 125 except (KeyError): 126 pass 127 return days_in_range 128 return dict.__getitem__(self, self.__keytransform__(key)) 129 130 def __setitem__(self, key, value): 131 if key in self: 132 if self.get(key).find(value) < 0 \ 133 and value.find(self.get(key)) < 0: 134 value = "%s, %s" % (value, self.get(key)) 135 else: 136 value = self.get(key) 137 return dict.__setitem__(self, self.__keytransform__(key), value) 138 139 def update(self, *args): 140 args = list(args) 141 for arg in args: 142 if isinstance(arg, dict): 143 for key, value in list(arg.items()): 144 self[key] = value 145 elif isinstance(arg, list): 146 for item in arg: 147 self[item] = "Holiday" 148 else: 149 self[arg] = "Holiday" 150 151 def append(self, *args): 152 return self.update(*args) 153 154 def get(self, key, default=None): 155 return dict.get(self, self.__keytransform__(key), default) 156 157 def get_list(self, key): 158 return [h for h in self.get(key, "").split(", ") if h] 159 160 def pop(self, key, default=None): 161 if default is None: 162 return dict.pop(self, self.__keytransform__(key)) 163 return dict.pop(self, self.__keytransform__(key), default) 164 165 def __eq__(self, other): 166 return dict.__eq__(self, other) and self.__dict__ == other.__dict__ 167 168 def __ne__(self, other): 169 return dict.__ne__(self, other) or self.__dict__ != other.__dict__ 170 171 def __add__(self, other): 172 if isinstance(other, int) and other == 0: 173 # Required to sum() list of holidays 174 # sum([h1, h2]) is equivalent to (0 + h1 + h2) 175 return self 176 elif not isinstance(other, HolidayBase): 177 raise TypeError() 178 HolidaySum = createHolidaySum(self, other) 179 country = (getattr(self, 'country', None) or 180 getattr(other, 'country', None)) 181 if self.country and other.country and self.country != other.country: 182 c1 = self.country 183 if not isinstance(c1, list): 184 c1 = [c1] 185 c2 = other.country 186 if not isinstance(c2, list): 187 c2 = [c2] 188 country = c1 + c2 189 prov = getattr(self, 'prov', None) or getattr(other, 'prov', None) 190 if self.prov and other.prov and self.prov != other.prov: 191 p1 = self.prov if isinstance(self.prov, list) else [self.prov] 192 p2 = other.prov if isinstance(other.prov, list) else [other.prov] 193 prov = p1 + p2 194 return HolidaySum(years=(self.years | other.years), 195 expand=(self.expand or other.expand), 196 observed=(self.observed or other.observed), 197 country=country, prov=prov) 198 199 def __radd__(self, other): 200 return self.__add__(other) 201 202 def _populate(self, year): 203 pass 204 205 206def createHolidaySum(h1, h2): 207 class HolidaySum(HolidayBase): 208 209 def __init__(self, country, **kwargs): 210 self.country = country 211 self.holidays = [] 212 if getattr(h1, 'holidays', False): 213 for h in h1.holidays: 214 self.holidays.append(h) 215 else: 216 self.holidays.append(h1) 217 if getattr(h2, 'holidays', False): 218 for h in h2.holidays: 219 self.holidays.append(h) 220 else: 221 self.holidays.append(h2) 222 HolidayBase.__init__(self, **kwargs) 223 224 def _populate(self, year): 225 for h in self.holidays[::-1]: 226 h._populate(year) 227 self.update(h) 228 229 return HolidaySum 230 231 232def list_supported_countries(): 233 """List all supported countries incl. their abbreviation.""" 234 return [name for name, obj in 235 inspect.getmembers(sys.modules[__name__], inspect.isclass) 236 if obj.__module__ is __name__] 237 238 239def CountryHoliday(country, years=[], prov=None, state=None, expand=True, 240 observed=True): 241 try: 242 country_holiday = globals()[country](years=years, 243 prov=prov, 244 state=state, 245 expand=expand, 246 observed=observed) 247 except (KeyError): 248 raise KeyError("Country %s not available" % country) 249 return country_holiday 250 251 252class Aruba(HolidayBase): 253 # http://www.gobierno.aw/informacion-tocante-servicio/vakantie-y-dia-di-fiesta_43437/item/dia-di-fiesta_14809.html 254 # https://www.visitaruba.com/about-aruba/national-holidays-and-celebrations/ 255 256 def __init__(self, **kwargs): 257 self.country = 'AW' 258 HolidayBase.__init__(self, **kwargs) 259 260 def _populate(self, year): 261 # New Year's Day 262 self[date(year, JAN, 1)] = "Aña Nobo [New Year's Day]" 263 264 # Dia di Betico 265 self[date(year, JAN, 25)] = "Dia Di Betico [Betico Day]" 266 267 # Carnaval Monday 268 self[easter(year) + rd(days=-48)] = "Dialuna di Carnaval \ 269 [Carnaval Monday]" 270 271 # Dia di Himno y Bandera 272 self[date(year, MAR, 18)] = "Dia di Himno y Bandera \ 273 [National Anthem & Flag Day]" 274 275 # Good Friday 276 self[easter(year) + rd(weekday=FR(-1))] = "Bierna Santo [Good Friday]" 277 278 # Easter Monday 279 self[easter(year) + rd(days=1)] = "Di Dos Dia di Pasco di Resureccion \ 280 [Easter Monday]" 281 282 # King's Day 283 if year >= 2014: 284 kings_day = date(year, APR, 27) 285 if kings_day.weekday() == 6: 286 kings_day = kings_day - rd(days=1) 287 288 self[kings_day] = "Aña di Rey [King's Day]" 289 290 # Queen's Day 291 if 1891 <= year <= 2013: 292 queens_day = date(year, APR, 30) 293 if year <= 1948: 294 queens_day = date(year, AUG, 31) 295 296 if queens_day.weekday() == 6: 297 if year < 1980: 298 queens_day = queens_day + rd(days=1) 299 else: 300 queens_day = queens_day - rd(days=1) 301 302 self[queens_day] = "Aña di La Reina [Queen's Day]" 303 304 # Labour Day 305 self[date(year, MAY, 1)] = "Dia di Obrero [Labour Day]" 306 307 # Ascension Day 308 self[easter(year) + rd(days=39)] = "Dia di Asuncion [Ascension Day]" 309 310 # Christmas Day 311 self[date(year, DEC, 25)] = "Pasco di Nacemento [Christmas]" 312 313 # Second Christmas 314 self[date(year, DEC, 26)] = "Di Dos Dia di Pasco di \ 315 Nacemento [Second Christmas]" 316 317 318class AW(Aruba): 319 pass 320 321 322class Argentina(HolidayBase): 323 # https://www.argentina.gob.ar/interior/feriados 324 # https://es.wikipedia.org/wiki/Anexo:D%C3%ADas_feriados_en_Argentina 325 # http://servicios.lanacion.com.ar/feriados 326 # https://www.clarin.com/feriados/ 327 328 def __init__(self, **kwargs): 329 self.country = 'AR' 330 HolidayBase.__init__(self, **kwargs) 331 332 def _populate(self, year): 333 # New Year's Day 334 if not self.observed and date(year, JAN, 1).weekday() in WEEKEND: 335 pass 336 else: 337 self[date(year, JAN, 1)] = "Año Nuevo [New Year's Day]" 338 339 # Carnival days 340 name = "Día de Carnaval [Carnival's Day]" 341 self[easter(year) - rd(days=48)] = name 342 self[easter(year) - rd(days=47)] = name 343 344 # Memory's National Day for the Truth and Justice 345 name = "Día Nacional de la Memoria por la Verdad y la Justicia " \ 346 "[Memory's National Day for the Truth and Justice]" 347 348 if not self.observed and date(year, MAR, 24).weekday() in WEEKEND: 349 pass 350 else: 351 self[date(year, MAR, 24)] = name 352 353 # Holy Week 354 name_thu = "Semana Santa (Jueves Santo) [Holy day (Holy Thursday)]" 355 name_fri = "Semana Santa (Viernes Santo) [Holy day (Holy Friday)]" 356 name_easter = 'Día de Pascuas [Easter Day]' 357 358 self[easter(year) + rd(weekday=TH(-1))] = name_thu 359 self[easter(year) + rd(weekday=FR(-1))] = name_fri 360 361 if not self.observed and easter(year).weekday() in WEEKEND: 362 pass 363 else: 364 self[easter(year)] = name_easter 365 366 # Veterans Day and the Fallen in the Malvinas War 367 if not self.observed and date(year, APR, 2).weekday() in WEEKEND: 368 pass 369 else: 370 self[date(year, APR, 2)] = "Día del Veterano y de los Caidos " \ 371 "en la Guerra de Malvinas [Veterans" \ 372 " Day and the Fallen in the" \ 373 " Malvinas War]" 374 375 # Labor Day 376 name = "Día del Trabajo [Labour Day]" 377 if not self.observed and date(year, MAY, 1).weekday() in WEEKEND: 378 pass 379 else: 380 self[date(year, MAY, 1)] = name 381 382 # May Revolution Day 383 name = "Día de la Revolucion de Mayo [May Revolution Day]" 384 if not self.observed and date(year, MAY, 25).weekday() in WEEKEND: 385 pass 386 else: 387 self[date(year, MAY, 25)] = name 388 389 # Day Pass to the Immortality of General Martín Miguel de Güemes. 390 name = "Día Pase a la Inmortalidad " \ 391 "del General Martín Miguel de Güemes [Day Pass " \ 392 "to the Immortality of General Martín Miguel de Güemes]" 393 if not self.observed and date(year, JUN, 17).weekday() in WEEKEND: 394 pass 395 else: 396 self[date(year, JUN, 17)] = name 397 398 # Day Pass to the Immortality of General D. Manuel Belgrano. 399 name = "Día Pase a la Inmortalidad " \ 400 "del General D. Manuel Belgrano [Day Pass " \ 401 "to the Immortality of General D. Manuel Belgrano]" 402 if not self.observed and date(year, JUN, 20).weekday() in WEEKEND: 403 pass 404 else: 405 self[date(year, JUN, 20)] = name 406 407 # Independence Day 408 name = "Día de la Independencia [Independence Day]" 409 if not self.observed and date(year, JUL, 9).weekday() in WEEKEND: 410 pass 411 else: 412 self[date(year, JUL, 9)] = name 413 414 # Day Pass to the Immortality of General D. José de San Martin 415 name = "Día Pase a la Inmortalidad " \ 416 "del General D. José de San Martin [Day Pass " \ 417 "to the Immortality of General D. José de San Martin]" 418 if not self.observed and date(year, AUG, 17).weekday() in WEEKEND: 419 pass 420 else: 421 self[date(year, AUG, 17)] = name 422 423 # Respect for Cultural Diversity Day or Columbus day 424 if not self.observed and date(year, OCT, 12).weekday() in WEEKEND: 425 pass 426 elif year < 2010: 427 self[date(year, OCT, 12)] = "Día de la Raza [Columbus day]" 428 else: 429 self[date(year, OCT, 12)] = "Día del Respeto a la Diversidad" \ 430 " Cultural [Respect for" \ 431 " Cultural Diversity Day]" 432 # National Sovereignty Day 433 name = "Día Nacional de la Soberanía [National Sovereignty Day]" 434 if not self.observed and date(year, NOV, 20).weekday() in WEEKEND: 435 pass 436 elif year >= 2010: 437 self[date(year, NOV, 20)] = name 438 439 # Immaculate Conception 440 if not self.observed and date(year, DEC, 8).weekday() in WEEKEND: 441 pass 442 else: 443 self[date(year, DEC, 8)] = "La Inmaculada Concepción" \ 444 " [Immaculate Conception]" 445 446 # Christmas 447 self[date(year, DEC, 25)] = "Navidad [Christmas]" 448 449 450class AR(Argentina): 451 pass 452 453 454class Belarus(HolidayBase): 455 """ 456 http://president.gov.by/en/holidays_en/ 457 http://www.belarus.by/en/about-belarus/national-holidays 458 """ 459 460 def __init__(self, **kwargs): 461 self.country = "BY" 462 HolidayBase.__init__(self, **kwargs) 463 464 def _populate(self, year): 465 # The current set of holidays came into force in 1998 466 # http://laws.newsby.org/documents/ukazp/pos05/ukaz05806.htm 467 if year <= 1998: 468 return 469 470 # New Year's Day 471 self[date(year, JAN, 1)] = "Новый год" 472 473 # Christmas Day (Orthodox) 474 self[date(year, JAN, 7)] = "Рождество Христово " \ 475 "(православное Рождество)" 476 477 # Women's Day 478 self[date(year, MAR, 8)] = "День женщин" 479 480 # Radunitsa ("Day of Rejoicing") 481 self[easter(year, method=EASTER_ORTHODOX) + rd(days=9)] = "Радуница" 482 483 # Labour Day 484 self[date(year, MAY, 1)] = "Праздник труда" 485 486 # Victory Day 487 self[date(year, MAY, 9)] = "День Победы" 488 489 # Independence Day 490 self[date(year, JUL, 3)] = "День Независимости Республики Беларусь " \ 491 "(День Республики)" 492 493 # October Revolution Day 494 self[date(year, NOV, 7)] = "День Октябрьской революции" 495 496 # Christmas Day (Catholic) 497 self[date(year, DEC, 25)] = "Рождество Христово " \ 498 "(католическое Рождество)" 499 500 501class BY(Belarus): 502 pass 503 504 505class Brazil(HolidayBase): 506 """ 507 https://pt.wikipedia.org/wiki/Feriados_no_Brasil 508 """ 509 510 STATES = ['AC', 'AL', 'AP', 'AM', 'BA', 'CE', 'DF', 'ES', 'GO', 'MA', 'MT', 511 'MS', 'MG', 'PA', 'PB', 'PE', 'PI', 'RJ', 'RN', 'RS', 'RO', 'RR', 512 'SC', 'SP', 'SE', 'TO'] 513 514 def __init__(self, **kwargs): 515 self.country = 'BR' 516 HolidayBase.__init__(self, **kwargs) 517 518 def _populate(self, year): 519 # New Year's Day 520 self[date(year, JAN, 1)] = "Ano novo" 521 522 self[date(year, APR, 21)] = "Tiradentes" 523 524 self[date(year, MAY, 1)] = "Dia Mundial do Trabalho" 525 526 self[date(year, SEP, 7)] = "Independência do Brasil" 527 528 self[date(year, OCT, 12)] = "Nossa Senhora Aparecida" 529 530 self[date(year, NOV, 2)] = "Finados" 531 532 self[date(year, NOV, 15)] = "Proclamação da República" 533 534 # Christmas Day 535 self[date(year, DEC, 25)] = "Natal" 536 537 self[easter(year) - rd(days=2)] = "Sexta-feira Santa" 538 539 self[easter(year)] = "Páscoa" 540 541 self[easter(year) + rd(days=60)] = "Corpus Christi" 542 543 quaresma = easter(year) - rd(days=46) 544 self[quaresma] = "Quarta-feira de cinzas (Início da Quaresma)" 545 546 self[quaresma - rd(weekday=TU(-1))] = "Carnaval" 547 548 if self.state == 'AC': 549 self[date(year, JAN, 23)] = "Dia do evangélico" 550 self[date(year, JUN, 15)] = "Aniversário do Acre" 551 self[date(year, SEP, 5)] = "Dia da Amazônia" 552 self[date(year, NOV, 17)] = "Assinatura do Tratado de" \ 553 " Petrópolis" 554 555 if self.state == 'AL': 556 self[date(year, JUN, 24)] = "São João" 557 self[date(year, JUN, 29)] = "São Pedro" 558 self[date(year, SEP, 16)] = "Emancipação política de Alagoas" 559 self[date(year, NOV, 20)] = "Consciência Negra" 560 561 if self.state == 'AP': 562 self[date(year, MAR, 19)] = "Dia de São José" 563 self[date(year, JUL, 25)] = "São Tiago" 564 self[date(year, OCT, 5)] = "Criação do estado" 565 self[date(year, NOV, 20)] = "Consciência Negra" 566 567 if self.state == 'AM': 568 self[date(year, SEP, 5)] = "Elevação do Amazonas" \ 569 " à categoria de província" 570 self[date(year, NOV, 20)] = "Consciência Negra" 571 self[date(year, DEC, 8)] = "Dia de Nossa Senhora da Conceição" 572 573 if self.state == 'BA': 574 self[date(year, JUL, 2)] = "Independência da Bahia" 575 576 if self.state == 'CE': 577 self[date(year, MAR, 19)] = "São José" 578 self[date(year, MAR, 25)] = "Data Magna do Ceará" 579 580 if self.state == 'DF': 581 self[date(year, APR, 21)] = "Fundação de Brasília" 582 self[date(year, NOV, 30)] = "Dia do Evangélico" 583 584 if self.state == 'ES': 585 self[date(year, OCT, 28)] = "Dia do Servidor Público" 586 587 if self.state == 'GO': 588 self[date(year, OCT, 28)] = "Dia do Servidor Público" 589 590 if self.state == 'MA': 591 self[date(year, JUL, 28)] = "Adesão do Maranhão" \ 592 " à independência do Brasil" 593 self[date(year, DEC, 8)] = "Dia de Nossa Senhora da Conceição" 594 595 if self.state == 'MT': 596 self[date(year, NOV, 20)] = "Consciência Negra" 597 598 if self.state == 'MS': 599 self[date(year, OCT, 11)] = "Criação do estado" 600 601 if self.state == 'MG': 602 self[date(year, APR, 21)] = "Data Magna de MG" 603 604 if self.state == 'PA': 605 self[date(year, AUG, 15)] = "Adesão do Grão-Pará" \ 606 " à independência do Brasil" 607 608 if self.state == 'PB': 609 self[date(year, AUG, 5)] = "Fundação do Estado" 610 611 if self.state == 'PE': 612 self[date(year, MAR, 6)] = "Revolução Pernambucana (Data Magna)" 613 self[date(year, JUN, 24)] = "São João" 614 615 if self.state == 'PI': 616 self[date(year, MAR, 13)] = "Dia da Batalha do Jenipapo" 617 self[date(year, OCT, 19)] = "Dia do Piauí" 618 619 if self.state == 'RJ': 620 self[date(year, APR, 23)] = "Dia de São Jorge" 621 self[date(year, OCT, 28)] = "Dia do Funcionário Público" 622 self[date(year, NOV, 20)] = "Zumbi dos Palmares" 623 624 if self.state == 'RN': 625 self[date(year, JUN, 29)] = "Dia de São Pedro" 626 self[date(year, OCT, 3)] = "Mártires de Cunhaú e Uruaçuu" 627 628 if self.state == 'RS': 629 self[date(year, SEP, 20)] = "Revolução Farroupilha" 630 631 if self.state == 'RO': 632 self[date(year, JAN, 4)] = "Criação do estado" 633 self[date(year, JUN, 18)] = "Dia do Evangélico" 634 635 if self.state == 'RR': 636 self[date(year, OCT, 5)] = "Criação de Roraima" 637 638 if self.state == 'SC': 639 self[date(year, AUG, 11)] = "Criação da capitania," \ 640 " separando-se de SP" 641 642 if self.state == 'SP': 643 self[date(year, JUL, 9)] = "Revolução Constitucionalista de 1932" 644 645 if self.state == 'SE': 646 self[date(year, JUL, 8)] = "Autonomia política de Sergipe" 647 648 if self.state == 'TO': 649 self[date(year, JAN, 1)] = "Instalação de Tocantins" 650 self[date(year, SEP, 8)] = "Nossa Senhora da Natividade" 651 self[date(year, OCT, 5)] = "Criação de Tocantins" 652 653 654class BR(Brazil): 655 pass 656 657 658class Bulgaria(HolidayBase): 659 """ 660 Official holidays in Bulgaria in their current form. This class does not 661 any return holidays before 1990, as holidays in the People's Republic of 662 Bulgaria and earlier were different. 663 664 Most holidays are fixed and if the date falls on a Saturday or a Sunday, 665 the following Monday is a non-working day. The exceptions are (1) the 666 Easter holidays, which are always a consecutive Friday, Saturday, and 667 Sunday; and (2) the National Awakening Day which, while an official holiday 668 and a non-attendance day for schools, is still a working day. 669 670 Sources (Bulgarian): 671 - http://lex.bg/laws/ldoc/1594373121 672 - https://www.parliament.bg/bg/24 673 674 Sources (English): 675 - https://en.wikipedia.org/wiki/Public_holidays_in_Bulgaria 676 """ 677 678 def __init__(self, **kwargs): 679 self.country = 'BG' 680 HolidayBase.__init__(self, **kwargs) 681 682 def _populate(self, year): 683 if year < 1990: 684 return 685 686 # New Year's Day 687 self[date(year, JAN, 1)] = "Нова година" 688 689 # Liberation Day 690 self[date(year, MAR, 3)] = \ 691 "Ден на Освобождението на България от османско иго" 692 693 # International Workers' Day 694 self[date(year, MAY, 1)] = \ 695 "Ден на труда и на международната работническа солидарност" 696 697 # Saint George's Day 698 self[date(year, MAY, 6)] = \ 699 "Гергьовден, Ден на храбростта и Българската армия" 700 701 # Bulgarian Education and Culture and Slavonic Literature Day 702 self[date(year, MAY, 24)] = \ 703 "Ден на българската просвета и култура и на славянската писменост" 704 705 # Unification Day 706 self[date(year, SEP, 6)] = "Ден на Съединението" 707 708 # Independence Day 709 self[date(year, SEP, 22)] = "Ден на Независимостта на България" 710 711 # National Awakening Day 712 self[date(year, NOV, 1)] = "Ден на народните будители" 713 714 # Christmas 715 self[date(year, DEC, 24)] = "Бъдни вечер" 716 self[date(year, DEC, 25)] = "Рождество Христово" 717 self[date(year, DEC, 26)] = "Рождество Христово" 718 719 # Easter 720 self[easter(year, method=EASTER_ORTHODOX)-rd(days=2)] = "Велики петък" 721 self[easter(year, method=EASTER_ORTHODOX)-rd(days=1)] = "Велика събота" 722 self[easter(year, method=EASTER_ORTHODOX)] = "Великден" 723 724 725class BG(Bulgaria): 726 pass 727 728 729class Canada(HolidayBase): 730 PROVINCES = ['AB', 'BC', 'MB', 'NB', 'NL', 'NS', 'NT', 'NU', 'ON', 'PE', 731 'QC', 'SK', 'YU'] 732 733 def __init__(self, **kwargs): 734 self.country = 'CA' 735 self.prov = kwargs.pop('prov', 'ON') 736 HolidayBase.__init__(self, **kwargs) 737 738 def _populate(self, year): 739 # New Year's Day 740 if year >= 1867: 741 name = "New Year's Day" 742 self[date(year, JAN, 1)] = name 743 if self.observed and date(year, JAN, 1).weekday() == SUN: 744 self[date(year, JAN, 1) + rd(days=+1)] = name + \ 745 " (Observed)" 746 elif self.observed \ 747 and date(year, JAN, 1).weekday() == SAT: 748 # Add Dec 31st from the previous year without triggering 749 # the entire year to be added 750 expand = self.expand 751 self.expand = False 752 self[date(year, JAN, 1) + rd(days=-1)] = name + \ 753 " (Observed)" 754 self.expand = expand 755 # The next year's observed New Year's Day can be in this year 756 # when it falls on a Friday (Jan 1st is a Saturday) 757 if self.observed and date(year, DEC, 31).weekday() == FRI: 758 self[date(year, DEC, 31)] = name + " (Observed)" 759 760 # Family Day / Louis Riel Day (MB) / Islander Day (PE) 761 # / Heritage Day (NS, YU) 762 if self.prov in ('AB', 'SK', 'ON') and year >= 2008: 763 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = "Family Day" 764 elif self.prov in ('AB', 'SK') and year >= 2007: 765 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = "Family Day" 766 elif self.prov == 'AB' and year >= 1990: 767 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = "Family Day" 768 elif self.prov == 'NB' and year >= 2018: 769 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = "Family Day" 770 elif self.prov == 'BC': 771 if year >= 2013 and year <= 2018: 772 self[date(year, FEB, 1) + rd(weekday=MO(+2))] = \ 773 "Family Day" 774 elif year > 2018: 775 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = \ 776 "Family Day" 777 elif self.prov == 'MB' and year >= 2008: 778 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = \ 779 "Louis Riel Day" 780 elif self.prov == 'PE' and year >= 2010: 781 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = "Islander Day" 782 elif self.prov == 'PE' and year == 2009: 783 self[date(year, FEB, 1) + rd(weekday=MO(+2))] = "Islander Day" 784 elif self.prov == 'NS' and year >= 2015: 785 # http://novascotia.ca/lae/employmentrights/NovaScotiaHeritageDay.asp 786 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = "Heritage Day" 787 elif self.prov == 'YU': 788 # start date? 789 # http://heritageyukon.ca/programs/heritage-day 790 # https://en.wikipedia.org/wiki/Family_Day_(Canada)#Yukon_Heritage_Day 791 # Friday before the last Sunday in February 792 dt = date(year, MAR, 1) + rd(weekday=SU(-1)) + rd(weekday=FR(-1)) 793 self[dt] = "Heritage Day" 794 795 # St. Patrick's Day 796 if self.prov == 'NL' and year >= 1900: 797 dt = date(year, MAR, 17) 798 # Nearest Monday to March 17 799 dt1 = date(year, MAR, 17) + rd(weekday=MO(-1)) 800 dt2 = date(year, MAR, 17) + rd(weekday=MO(+1)) 801 if dt2 - dt <= dt - dt1: 802 self[dt2] = "St. Patrick's Day" 803 else: 804 self[dt1] = "St. Patrick's Day" 805 806 # Good Friday 807 if self.prov != 'QC' and year >= 1867: 808 self[easter(year) + rd(weekday=FR(-1))] = "Good Friday" 809 810 # Easter Monday 811 if self.prov == 'QC' and year >= 1867: 812 self[easter(year) + rd(weekday=MO)] = "Easter Monday" 813 814 # St. George's Day 815 if self.prov == 'NL' and year == 2010: 816 # 4/26 is the Monday closer to 4/23 in 2010 817 # but the holiday was observed on 4/19? Crazy Newfies! 818 self[date(2010, 4, 19)] = "St. George's Day" 819 elif self.prov == 'NL' and year >= 1990: 820 dt = date(year, APR, 23) 821 # Nearest Monday to April 23 822 dt1 = dt + rd(weekday=MO(-1)) 823 dt2 = dt + rd(weekday=MO(+1)) 824 if dt2 - dt < dt - dt1: 825 self[dt2] = "St. George's Day" 826 else: 827 self[dt1] = "St. George's Day" 828 829 # Victoria Day / National Patriots' Day (QC) 830 if self.prov not in ('NB', 'NS', 'PE', 'NL', 'QC') and year >= 1953: 831 self[date(year, MAY, 24) + rd(weekday=MO(-1))] = "Victoria Day" 832 elif self.prov == 'QC' and year >= 1953: 833 name = "National Patriots' Day" 834 self[date(year, MAY, 24) + rd(weekday=MO(-1))] = name 835 836 # National Aboriginal Day 837 if self.prov == 'NT' and year >= 1996: 838 self[date(year, JUN, 21)] = "National Aboriginal Day" 839 840 # St. Jean Baptiste Day 841 if self.prov == 'QC' and year >= 1925: 842 self[date(year, JUN, 24)] = "St. Jean Baptiste Day" 843 if self.observed and date(year, JUN, 24).weekday() == SUN: 844 self[date(year, JUN, 25)] = "St. Jean Baptiste Day (Observed)" 845 846 # Discovery Day 847 if self.prov == 'NL' and year >= 1997: 848 dt = date(year, JUN, 24) 849 # Nearest Monday to June 24 850 dt1 = dt + rd(weekday=MO(-1)) 851 dt2 = dt + rd(weekday=MO(+1)) 852 if dt2 - dt <= dt - dt1: 853 self[dt2] = "Discovery Day" 854 else: 855 self[dt1] = "Discovery Day" 856 elif self.prov == 'YU' and year >= 1912: 857 self[date(year, AUG, 1) + rd(weekday=MO(+3))] = "Discovery Day" 858 859 # Canada Day / Memorial Day (NL) 860 if self.prov != 'NL' and year >= 1867: 861 if year >= 1983: 862 name = "Canada Day" 863 else: 864 name = "Dominion Day" 865 self[date(year, JUL, 1)] = name 866 if year >= 1879 and self.observed \ 867 and date(year, JUL, 1).weekday() in WEEKEND: 868 self[date(year, JUL, 1) + rd(weekday=MO)] = name + \ 869 " (Observed)" 870 elif year >= 1867: 871 if year >= 1983: 872 name = "Memorial Day" 873 else: 874 name = "Dominion Day" 875 self[date(year, JUL, 1)] = name 876 if year >= 1879 and self.observed \ 877 and date(year, JUL, 1).weekday() in WEEKEND: 878 self[date(year, JUL, 1) + rd(weekday=MO)] = name + \ 879 " (Observed)" 880 881 # Nunavut Day 882 if self.prov == 'NU' and year >= 2001: 883 self[date(year, JUL, 9)] = "Nunavut Day" 884 if self.observed and date(year, JUL, 9).weekday() == SUN: 885 self[date(year, JUL, 10)] = "Nunavut Day (Observed)" 886 elif self.prov == 'NU' and year == 2000: 887 self[date(2000, 4, 1)] = "Nunavut Day" 888 889 # Civic Holiday 890 if self.prov in ('ON', 'MB', 'NT') and year >= 1900: 891 self[date(year, AUG, 1) + rd(weekday=MO)] = "Civic Holiday" 892 elif self.prov == 'AB' and year >= 1974: 893 # https://en.wikipedia.org/wiki/Civic_Holiday#Alberta 894 self[date(year, AUG, 1) + rd(weekday=MO)] = "Heritage Day" 895 elif self.prov == 'BC' and year >= 1974: 896 # https://en.wikipedia.org/wiki/Civic_Holiday 897 self[date(year, AUG, 1) + rd(weekday=MO)] = \ 898 "British Columbia Day" 899 elif self.prov == 'NB' and year >= 1900: 900 # https://en.wikipedia.org/wiki/Civic_Holiday 901 self[date(year, AUG, 1) + rd(weekday=MO)] = "New Brunswick Day" 902 elif self.prov == 'SK' and year >= 1900: 903 # https://en.wikipedia.org/wiki/Civic_Holiday 904 self[date(year, AUG, 1) + rd(weekday=MO)] = "Saskatchewan Day" 905 906 # Labour Day 907 if year >= 1894: 908 self[date(year, SEP, 1) + rd(weekday=MO)] = "Labour Day" 909 910 # Thanksgiving 911 if self.prov not in ('NB', 'NS', 'PE', 'NL') and year >= 1931: 912 if year == 1935: 913 # in 1935, Canadian Thanksgiving was moved due to the General 914 # Election falling on the second Monday of October 915 # https://books.google.ca/books?id=KcwlQsmheG4C&pg=RA1-PA1940&lpg=RA1-PA1940&dq=canada+thanksgiving+1935&source=bl&ots=j4qYrcfGuY&sig=gxXeAQfXVsOF9fOwjSMswPHJPpM&hl=en&sa=X&ved=0ahUKEwjO0f3J2PjOAhVS4mMKHRzKBLAQ6AEIRDAG#v=onepage&q=canada%20thanksgiving%201935&f=false 916 self[date(1935, 10, 25)] = "Thanksgiving" 917 else: 918 self[date(year, OCT, 1) + rd(weekday=MO(+2))] = \ 919 "Thanksgiving" 920 921 # Remembrance Day 922 name = "Remembrance Day" 923 provinces = ('ON', 'QC', 'NS', 'NL', 'NT', 'PE', 'SK') 924 if self.prov not in provinces and year >= 1931: 925 self[date(year, NOV, 11)] = name 926 elif self.prov in ('NS', 'NL', 'NT', 'PE', 'SK') and year >= 1931: 927 self[date(year, NOV, 11)] = name 928 if self.observed and date(year, NOV, 11).weekday() == SUN: 929 name = name + " (Observed)" 930 self[date(year, NOV, 11) + rd(weekday=MO)] = name 931 932 # Christmas Day 933 if year >= 1867: 934 self[date(year, DEC, 25)] = "Christmas Day" 935 if self.observed \ 936 and date(year, DEC, 25).weekday() == SAT: 937 self[date(year, DEC, 24)] = "Christmas Day (Observed)" 938 elif self.observed \ 939 and date(year, DEC, 25).weekday() == SUN: 940 self[date(year, DEC, 26)] = "Christmas Day (Observed)" 941 942 # Boxing Day 943 if year >= 1867: 944 name = "Boxing Day" 945 name_observed = name + " (Observed)" 946 if self.observed and date(year, DEC, 26).weekday() in WEEKEND: 947 self[date(year, DEC, 26) + rd(weekday=MO)] = name_observed 948 elif self.observed and date(year, DEC, 26).weekday() == 0: 949 self[date(year, DEC, 27)] = name_observed 950 else: 951 self[date(year, DEC, 26)] = name 952 953 954class CA(Canada): 955 pass 956 957 958class Chile(HolidayBase): 959 # https://www.feriados.cl 960 # https://es.wikipedia.org/wiki/Anexo:D%C3%ADas_feriados_en_Chile 961 962 def __init__(self, **kwargs): 963 self.country = 'CL' 964 HolidayBase.__init__(self, **kwargs) 965 966 def _populate(self, year): 967 # New Year's Day 968 self[date(year, JAN, 1)] = "Año Nuevo [New Year's Day]" 969 970 # Holy Week 971 name_fri = "Semana Santa (Viernes Santo) [Holy day (Holy Friday)]" 972 name_easter = 'Día de Pascuas [Easter Day]' 973 974 self[easter(year) + rd(weekday=FR(-1))] = name_fri 975 self[easter(year)] = name_easter 976 977 # Labor Day 978 name = "Día del Trabajo [Labour Day]" 979 self[date(year, MAY, 1)] = name 980 981 # Naval Glories Day 982 name = "Día de las Glorias Navales [Naval Glories Day]" 983 self[date(year, MAY, 21)] = name 984 985 # Saint Peter and Saint Paul. 986 name = "San Pedro y San Pablo [Saint Peter and Saint Paul]" 987 self[date(year, JUN, 29)] = name 988 989 # Day of Virgin of Carmen. 990 name = "Virgen del Carmen [Virgin of Carmen]" 991 self[date(year, JUL, 16)] = name 992 993 # Day of Assumption of the Virgin 994 name = "Asunsión de la Virgen [Assumption of the Virgin]" 995 self[date(year, AUG, 15)] = name 996 997 # Independence Day 998 name = "Día de la Independencia [Independence Day]" 999 self[date(year, SEP, 18)] = name 1000 1001 # Day of Glories of the Army of Chile 1002 name = "Día de las Glorias del Ejército de Chile [Day of " \ 1003 "Glories of the Army of Chile]" 1004 self[date(year, SEP, 19)] = name 1005 # National Holidays Ley 20.215 1006 name = "Fiestas Patrias [National Holidays]" 1007 if year > 2014 and date(year, SEP, 19).weekday() in [WED, THU]: 1008 self[date(year, SEP, 20)] = name 1009 1010 # Day of the Meeting of Two Worlds 1011 if year < 2010: 1012 self[date(year, OCT, 12)] = "Día de la Raza [Columbus day]" 1013 else: 1014 self[date(year, OCT, 12)] = "Día del Respeto a la Diversidad" \ 1015 " [Day of the Meeting " \ 1016 " of Two Worlds]" 1017 1018 # National Day of the Evangelical and Protestant Churches 1019 name = "Día Nacional de las Iglesias Evangélicas y Protestantes " \ 1020 " [National Day of the " \ 1021 " Evangelical and " \ 1022 " Protestant Churches]" 1023 self[date(year, OCT, 31)] = name 1024 1025 # All Saints Day 1026 name = "Día de Todos los Santos [All Saints Day]" 1027 self[date(year, NOV, 1)] = name 1028 1029 # Immaculate Conception 1030 self[date(year, DEC, 8)] = "La Inmaculada Concepción" \ 1031 " [Immaculate Conception]" 1032 1033 # Christmas 1034 self[date(year, DEC, 25)] = "Navidad [Christmas]" 1035 1036 1037class CL(Chile): 1038 pass 1039 1040 1041class Colombia(HolidayBase): 1042 # https://es.wikipedia.org/wiki/Anexo:D%C3%ADas_festivos_en_Colombia 1043 1044 def __init__(self, **kwargs): 1045 self.country = 'CO' 1046 HolidayBase.__init__(self, **kwargs) 1047 1048 def _populate(self, year): 1049 1050 # Fixed date holidays! 1051 # If observed=True and they fall on a weekend they are not observed. 1052 # If observed=False there are 18 holidays 1053 1054 # New Year's Day 1055 if self.observed and date(year, JAN, 1).weekday() in WEEKEND: 1056 pass 1057 else: 1058 self[date(year, JAN, 1)] = "Año Nuevo [New Year's Day]" 1059 1060 # Labor Day 1061 self[date(year, MAY, 1)] = "Día del Trabajo [Labour Day]" 1062 1063 # Independence Day 1064 name = "Día de la Independencia [Independence Day]" 1065 if self.observed and date(year, JUL, 20).weekday() in WEEKEND: 1066 pass 1067 else: 1068 self[date(year, JUL, 20)] = name 1069 1070 # Battle of Boyaca 1071 self[date(year, AUG, 7)] = "Batalla de Boyacá [Battle of Boyacá]" 1072 1073 # Immaculate Conception 1074 if self.observed and date(year, DEC, 8).weekday() in WEEKEND: 1075 pass 1076 else: 1077 self[date(year, DEC, 8)] = "La Inmaculada Concepción" \ 1078 " [Immaculate Conception]" 1079 1080 # Christmas 1081 self[date(year, DEC, 25)] = "Navidad [Christmas]" 1082 1083 # Emiliani Law holidays! 1084 # Unless they fall on a Monday they are observed the following monday 1085 1086 # Epiphany 1087 name = "Día de los Reyes Magos [Epiphany]" 1088 if date(year, JAN, 6).weekday() == MON or not self.observed: 1089 self[date(year, JAN, 6)] = name 1090 else: 1091 self[date(year, JAN, 6) + rd(weekday=MO)] = name + "(Observed)" 1092 1093 # Saint Joseph's Day 1094 name = "Día de San José [Saint Joseph's Day]" 1095 if date(year, MAR, 19).weekday() == MON or not self.observed: 1096 self[date(year, MAR, 19)] = name 1097 else: 1098 self[date(year, MAR, 19) + rd(weekday=MO)] = name + "(Observed)" 1099 1100 # Saint Peter and Saint Paul's Day 1101 name = "San Pedro y San Pablo [Saint Peter and Saint Paul]" 1102 if date(year, JUN, 29).weekday() == MON or not self.observed: 1103 self[date(year, JUN, 29)] = name 1104 else: 1105 self[date(year, JUN, 29) + rd(weekday=MO)] = name + "(Observed)" 1106 1107 # Assumption of Mary 1108 name = "La Asunción [Assumption of Mary]" 1109 if date(year, AUG, 15).weekday() == MON or not self.observed: 1110 self[date(year, AUG, 15)] = name 1111 else: 1112 self[date(year, AUG, 15) + rd(weekday=MO)] = name + "(Observed)" 1113 1114 # Discovery of America 1115 name = "Descubrimiento de América [Discovery of America]" 1116 if date(year, OCT, 12).weekday() == MON or not self.observed: 1117 self[date(year, OCT, 12)] = name 1118 else: 1119 self[date(year, OCT, 12) + rd(weekday=MO)] = name + \ 1120 "(Observed)" 1121 1122 # All Saints’ Day 1123 name = "Dia de Todos los Santos [All Saint's Day]" 1124 if date(year, NOV, 1).weekday() == MON or not self.observed: 1125 self[date(year, NOV, 1)] = name 1126 else: 1127 self[date(year, NOV, 1) + rd(weekday=MO)] = name + \ 1128 "(Observed)" 1129 1130 # Independence of Cartagena 1131 name = "Independencia de Cartagena [Independence of Cartagena]" 1132 if date(year, NOV, 11).weekday() == MON or not self.observed: 1133 self[date(year, NOV, 11)] = name 1134 else: 1135 self[date(year, NOV, 11) + rd(weekday=MO)] = name + \ 1136 "(Observed)" 1137 1138 # Holidays based on Easter 1139 1140 # Maundy Thursday 1141 self[easter(year) + rd(weekday=TH(-1)) 1142 ] = "Jueves Santo [Maundy Thursday]" 1143 1144 # Good Friday 1145 self[easter(year) + rd(weekday=FR(-1)) 1146 ] = "Viernes Santo [Good Friday]" 1147 1148 # Holidays based on Easter but are observed the following monday 1149 # (unless they occur on a monday) 1150 1151 # Ascension of Jesus 1152 name = "Ascensión del señor [Ascension of Jesus]" 1153 hdate = easter(year) + rd(days=+39) 1154 if hdate.weekday() == MON or not self.observed: 1155 self[hdate] = name 1156 else: 1157 self[hdate + rd(weekday=MO)] = name + "(Observed)" 1158 1159 # Corpus Christi 1160 name = "Corpus Christi [Corpus Christi]" 1161 hdate = easter(year) + rd(days=+60) 1162 if hdate.weekday() == MON or not self.observed: 1163 self[hdate] = name 1164 else: 1165 self[hdate + rd(weekday=MO)] = name + "(Observed)" 1166 1167 # Sacred Heart 1168 name = "Sagrado Corazón [Sacred Heart]" 1169 hdate = easter(year) + rd(days=+68) 1170 if hdate.weekday() == MON or not self.observed: 1171 self[hdate] = name 1172 else: 1173 self[hdate + rd(weekday=MO)] = name + "(Observed)" 1174 1175 1176class CO(Colombia): 1177 pass 1178 1179 1180class Mexico(HolidayBase): 1181 1182 def __init__(self, **kwargs): 1183 self.country = 'MX' 1184 HolidayBase.__init__(self, **kwargs) 1185 1186 def _populate(self, year): 1187 # New Year's Day 1188 name = "Año Nuevo [New Year's Day]" 1189 self[date(year, JAN, 1)] = name 1190 if self.observed and date(year, JAN, 1).weekday() == SUN: 1191 self[date(year, JAN, 1) + rd(days=+1)] = name + " (Observed)" 1192 elif self.observed and date(year, JAN, 1).weekday() == SAT: 1193 # Add Dec 31st from the previous year without triggering 1194 # the entire year to be added 1195 expand = self.expand 1196 self.expand = False 1197 self[date(year, JAN, 1) + rd(days=-1)] = name + " (Observed)" 1198 self.expand = expand 1199 # The next year's observed New Year's Day can be in this year 1200 # when it falls on a Friday (Jan 1st is a Saturday) 1201 if self.observed and date(year, DEC, 31).weekday() == FRI: 1202 self[date(year, DEC, 31)] = name + " (Observed)" 1203 1204 # Constitution Day 1205 name = "Día de la Constitución [Constitution Day]" 1206 if 2006 >= year >= 1917: 1207 self[date(year, FEB, 5)] = name 1208 elif year >= 2007: 1209 self[date(year, FEB, 1) + rd(weekday=MO(+1))] = name 1210 1211 # Benito Juárez's birthday 1212 name = "Natalicio de Benito Juárez [Benito Juárez's birthday]" 1213 if 2006 >= year >= 1917: 1214 self[date(year, MAR, 21)] = name 1215 elif year >= 2007: 1216 self[date(year, MAR, 1) + rd(weekday=MO(+3))] = name 1217 1218 # Labor Day 1219 if year >= 1923: 1220 self[date(year, MAY, 1)] = "Día del Trabajo [Labour Day]" 1221 if self.observed and date(year, MAY, 1).weekday() == SAT: 1222 self[date(year, MAY, 1) + rd(days=-1)] = name + " (Observed)" 1223 elif self.observed and date(year, MAY, 1).weekday() == SUN: 1224 self[date(year, MAY, 1) + rd(days=+1)] = name + " (Observed)" 1225 1226 # Independence Day 1227 name = "Día de la Independencia [Independence Day]" 1228 self[date(year, SEP, 16)] = name 1229 if self.observed and date(year, SEP, 16).weekday() == SAT: 1230 self[date(year, SEP, 16) + rd(days=-1)] = name + \ 1231 " (Observed)" 1232 elif self.observed and date(year, SEP, 16).weekday() == SUN: 1233 self[date(year, SEP, 16) + rd(days=+1)] = name + \ 1234 " (Observed)" 1235 1236 # Revolution Day 1237 name = "Día de la Revolución [Revolution Day]" 1238 if 2006 >= year >= 1917: 1239 self[date(year, NOV, 20)] = name 1240 elif year >= 2007: 1241 self[date(year, NOV, 1) + rd(weekday=MO(+3))] = name 1242 1243 # Change of Federal Government 1244 # Every six years--next observance 2018 1245 name = "Transmisión del Poder Ejecutivo Federal" 1246 name += " [Change of Federal Government]" 1247 if (2018 - year) % 6 == 0: 1248 self[date(year, DEC, 1)] = name 1249 if self.observed \ 1250 and date(year, DEC, 1).weekday() == SAT: 1251 self[date(year, DEC, 1) + rd(days=-1)] = name + \ 1252 " (Observed)" 1253 elif self.observed \ 1254 and date(year, DEC, 1).weekday() == SUN: 1255 self[date(year, DEC, 1) + rd(days=+1)] = name + \ 1256 " (Observed)" 1257 1258 # Christmas 1259 self[date(year, DEC, 25)] = "Navidad [Christmas]" 1260 if self.observed and date(year, DEC, 25).weekday() == SAT: 1261 self[date(year, DEC, 25) + rd(days=-1)] = name + " (Observed)" 1262 elif self.observed and date(year, DEC, 25).weekday() == SUN: 1263 self[date(year, DEC, 25) + rd(days=+1)] = name + " (Observed)" 1264 1265 1266class MX(Mexico): 1267 pass 1268 1269 1270class Ukraine(HolidayBase): 1271 """ 1272 http://zakon1.rada.gov.ua/laws/show/322-08/paran454#n454 1273 """ 1274 1275 def __init__(self, **kwargs): 1276 self.country = "UA" 1277 HolidayBase.__init__(self, **kwargs) 1278 1279 def _populate(self, year): 1280 # The current set of holidays came into force in 1991 1281 # But most holiday days was inplemented in 1981 1282 if year < 1918: 1283 return 1284 1285 # New Year's Day 1286 if year >= 1898: 1287 self[date(year, JAN, 1)] = "Новий рік" 1288 1289 # Christmas Day (Orthodox) 1290 if year >= 1991: 1291 self[date(year, JAN, 7)] = "Різдво Христове" \ 1292 " (православне)" 1293 1294 # Women's Day 1295 if year > 1965: 1296 self[date(year, MAR, 8)] = "Міжнародний жіночий день" 1297 1298 # Easter 1299 if year >= 1991: 1300 self[easter(year, method=EASTER_ORTHODOX)] = "Пасха" \ 1301 " (Великдень)" 1302 1303 # Holy trinity 1304 if year >= 1991: 1305 self[easter(year, method=EASTER_ORTHODOX) + rd(days=49)] = "Трійця" 1306 1307 # Labour Day 1308 if year > 2017: 1309 name = "День праці" 1310 elif 1917 < year <= 2017: 1311 name = "День міжнародної солідарності трудящих" 1312 self[date(year, MAY, 1)] = name 1313 1314 # Labour Day in past 1315 if 1928 < year < 2018: 1316 self[date(year, MAY, 2)] = "День міжнародної солідарності трудящих" 1317 1318 # Victory Day 1319 name = "День перемоги" 1320 if year >= 1965: 1321 self[date(year, MAY, 9)] = name 1322 if 1945 <= year < 1947: 1323 self[date(year, MAY, 9)] = name 1324 self[date(year, SEP, 3)] = "День перемоги над Японією" 1325 1326 # Constitution Day 1327 if year >= 1997: 1328 self[date(year, JUN, 28)] = "День Конституції України" 1329 1330 # Independence Day 1331 name = "День незалежності України" 1332 if year > 1991: 1333 self[date(year, AUG, 24)] = name 1334 elif year == 1991: 1335 self[date(year, JUL, 16)] = name 1336 1337 # Day of the defender of Ukraine 1338 if year >= 2015: 1339 self[date(year, OCT, 14)] = "День захисника України" 1340 1341 # USSR Constitution day 1342 name = "День Конституції СРСР" 1343 if 1981 <= year < 1991: 1344 self[date(year, OCT, 7)] = name 1345 elif 1937 <= year < 1981: 1346 self[date(year, DEC, 5)] = name 1347 1348 # October Revolution 1349 if 1917 < year < 2000: 1350 if year <= 1991: 1351 name = "Річниця Великої Жовтневої" \ 1352 " соціалістичної революції" 1353 else: 1354 name = "Річниця жовтневого перевороту" 1355 self[date(year, NOV, 7)] = name 1356 self[date(year, NOV, 8)] = name 1357 1358 # Christmas Day (Catholic) 1359 if year >= 2017: 1360 self[date(year, DEC, 25)] = "Різдво Христове" \ 1361 " (католицьке)" 1362 # USSR holidays 1363 # Bloody_Sunday_(1905) 1364 if 1917 <= year < 1951: 1365 self[date(year, JAN, 22)] = "День пам'яті 9 січня 1905 року" 1366 1367 # Paris_Commune 1368 if 1917 < year < 1929: 1369 self[date(year, MAR, 18)] = "День паризької комуни" 1370 1371 1372class UA(Ukraine): 1373 pass 1374 1375 1376class UnitedStates(HolidayBase): 1377 # https://en.wikipedia.org/wiki/Public_holidays_in_the_United_States 1378 1379 STATES = ['AL', 'AK', 'AS', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL', 1380 'GA', 'GU', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 1381 'MD', 'MH', 'MA', 'MI', 'FM', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 1382 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'MP', 'OH', 'OK', 'OR', 'PW', 1383 'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'VI', 1384 'WA', 'WV', 'WI', 'WY'] 1385 1386 def __init__(self, **kwargs): 1387 self.country = 'US' 1388 HolidayBase.__init__(self, **kwargs) 1389 1390 def _populate(self, year): 1391 # New Year's Day 1392 if year > 1870: 1393 name = "New Year's Day" 1394 self[date(year, JAN, 1)] = name 1395 if self.observed and date(year, JAN, 1).weekday() == SUN: 1396 self[date(year, JAN, 1) + rd(days=+1)] = name + \ 1397 " (Observed)" 1398 elif self.observed \ 1399 and date(year, JAN, 1).weekday() == SAT: 1400 # Add Dec 31st from the previous year without triggering 1401 # the entire year to be added 1402 expand = self.expand 1403 self.expand = False 1404 self[date(year, JAN, 1) + rd(days=-1)] = name + \ 1405 " (Observed)" 1406 self.expand = expand 1407 # The next year's observed New Year's Day can be in this year 1408 # when it falls on a Friday (Jan 1st is a Saturday) 1409 if self.observed and date(year, DEC, 31).weekday() == FRI: 1410 self[date(year, DEC, 31)] = name + " (Observed)" 1411 1412 # Epiphany 1413 if self.state == 'PR': 1414 self[date(year, JAN, 6)] = "Epiphany" 1415 1416 # Three King's Day 1417 if self.state == 'VI': 1418 self[date(year, JAN, 6)] = "Three King's Day" 1419 1420 # Lee Jackson Day 1421 name = "Lee Jackson Day" 1422 if self.state == 'VA' and year >= 2000: 1423 dt = date(year, JAN, 1) + rd(weekday=MO(+3)) + rd( 1424 weekday=FR(-1)) 1425 self[dt] = name 1426 elif self.state == 'VA' and year >= 1983: 1427 self[date(year, JAN, 1) + rd(weekday=MO(+3))] = name 1428 elif self.state == 'VA' and year >= 1889: 1429 self[date(year, JAN, 19)] = name 1430 1431 # Inauguration Day 1432 if self.state in ('DC', 'LA', 'MD', 'VA') and year >= 1789: 1433 name = "Inauguration Day" 1434 if (year - 1789) % 4 == 0 and year >= 1937: 1435 self[date(year, JAN, 20)] = name 1436 if date(year, JAN, 20).weekday() == SUN: 1437 self[date(year, JAN, 21)] = name + " (Observed)" 1438 elif (year - 1789) % 4 == 0: 1439 self[date(year, MAR, 4)] = name 1440 if date(year, MAR, 4).weekday() == SUN: 1441 self[date(year, MAR, 5)] = name + " (Observed)" 1442 1443 # Martin Luther King, Jr. Day 1444 if year >= 1986: 1445 name = "Martin Luther King, Jr. Day" 1446 if self.state == 'AL': 1447 name = "Robert E. Lee/Martin Luther King Birthday" 1448 elif self.state in ('AS', 'MS'): 1449 name = ("Dr. Martin Luther King Jr. " 1450 "and Robert E. Lee's Birthdays") 1451 elif self.state in ('AZ', 'NH'): 1452 name = "Dr. Martin Luther King Jr./Civil Rights Day" 1453 elif self.state == 'GA' and year < 2012: 1454 name = "Robert E. Lee's Birthday" 1455 elif self.state == 'ID' and year >= 2006: 1456 name = "Martin Luther King, Jr. - Idaho Human Rights Day" 1457 self[date(year, JAN, 1) + rd(weekday=MO(+3))] = name 1458 1459 # Lincoln's Birthday 1460 name = "Lincoln's Birthday" 1461 if (self.state in ('CT', 'IL', 'IA', 'NJ', 'NY') and year >= 1971) \ 1462 or (self.state == 'CA' and 1971 <= year <= 2009): 1463 self[date(year, FEB, 12)] = name 1464 if self.observed \ 1465 and date(year, FEB, 12).weekday() == SAT: 1466 self[date(year, FEB, 11)] = name + " (Observed)" 1467 elif self.observed \ 1468 and date(year, FEB, 12).weekday() == SUN: 1469 self[date(year, FEB, 13)] = name + " (Observed)" 1470 1471 # Susan B. Anthony Day 1472 if (self.state == 'CA' and year >= 2014) \ 1473 or (self.state == 'FL' and year >= 2011) \ 1474 or (self.state == 'NY' and year >= 2004) \ 1475 or (self.state == 'WI' and year >= 1976): 1476 self[date(year, FEB, 15)] = "Susan B. Anthony Day" 1477 1478 # Washington's Birthday 1479 name = "Washington's Birthday" 1480 if self.state == 'AL': 1481 name = "George Washington/Thomas Jefferson Birthday" 1482 elif self.state == 'AS': 1483 name = "George Washington's Birthday and Daisy Gatson Bates Day" 1484 elif self.state in ('PR', 'VI'): 1485 name = "Presidents' Day" 1486 if self.state not in ('DE', 'FL', 'GA', 'NM', 'PR'): 1487 if year > 1970: 1488 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = name 1489 elif year >= 1879: 1490 self[date(year, FEB, 22)] = name 1491 elif self.state == 'GA': 1492 if date(year, DEC, 24).weekday() != WED: 1493 self[date(year, DEC, 24)] = name 1494 else: 1495 self[date(year, DEC, 26)] = name 1496 elif self.state in ('PR', 'VI'): 1497 self[date(year, FEB, 1) + rd(weekday=MO(+3))] = name 1498 1499 # Mardi Gras 1500 if self.state == 'LA' and year >= 1857: 1501 self[easter(year) + rd(days=-47)] = "Mardi Gras" 1502 1503 # Guam Discovery Day 1504 if self.state == 'GU' and year >= 1970: 1505 self[date(year, MAR, 1) + rd(weekday=MO)] = "Guam Discovery Day" 1506 1507 # Casimir Pulaski Day 1508 if self.state == 'IL' and year >= 1978: 1509 self[date(year, MAR, 1) + rd(weekday=MO)] = "Casimir Pulaski Day" 1510 1511 # Texas Independence Day 1512 if self.state == 'TX' and year >= 1874: 1513 self[date(year, MAR, 2)] = "Texas Independence Day" 1514 1515 # Town Meeting Day 1516 if self.state == 'VT' and year >= 1800: 1517 self[date(year, MAR, 1) + rd(weekday=TU)] = "Town Meeting Day" 1518 1519 # Evacuation Day 1520 if self.state == 'MA' and year >= 1901: 1521 name = "Evacuation Day" 1522 self[date(year, MAR, 17)] = name 1523 if date(year, MAR, 17).weekday() in WEEKEND: 1524 self[date(year, MAR, 17) + rd(weekday=MO)] = name + \ 1525 " (Observed)" 1526 1527 # Emancipation Day 1528 if self.state == 'PR': 1529 self[date(year, MAR, 22)] = "Emancipation Day" 1530 if self.observed and date(year, MAR, 22).weekday() == SUN: 1531 self[date(year, MAR, 23)] = "Emancipation Day (Observed)" 1532 1533 # Prince Jonah Kuhio Kalanianaole Day 1534 if self.state == 'HI' and year >= 1949: 1535 name = "Prince Jonah Kuhio Kalanianaole Day" 1536 self[date(year, MAR, 26)] = name 1537 if self.observed and date(year, MAR, 26).weekday() == SAT: 1538 self[date(year, MAR, 25)] = name + " (Observed)" 1539 elif self.observed and date(year, MAR, 26).weekday() == SUN: 1540 self[date(year, MAR, 27)] = name + " (Observed)" 1541 1542 # Steward's Day 1543 name = "Steward's Day" 1544 if self.state == 'AK' and year >= 1955: 1545 self[date(year, APR, 1) + rd(days=-1, weekday=MO(-1))] = name 1546 elif self.state == 'AK' and year >= 1918: 1547 self[date(year, MAR, 30)] = name 1548 1549 # César Chávez Day 1550 name = "César Chávez Day" 1551 if self.state == 'CA' and year >= 1995: 1552 self[date(year, MAR, 31)] = name 1553 if self.observed and date(year, MAR, 31).weekday() == SUN: 1554 self[date(year, APR, 1)] = name + " (Observed)" 1555 elif self.state == 'TX' and year >= 2000: 1556 self[date(year, MAR, 31)] = name 1557 1558 # Transfer Day 1559 if self.state == 'VI': 1560 self[date(year, MAR, 31)] = "Transfer Day" 1561 1562 # Emancipation Day 1563 if self.state == 'DC' and year >= 2005: 1564 name = "Emancipation Day" 1565 self[date(year, APR, 16)] = name 1566 if self.observed and date(year, APR, 16).weekday() == SAT: 1567 self[date(year, APR, 15)] = name + " (Observed)" 1568 elif self.observed and date(year, APR, 16).weekday() == SUN: 1569 self[date(year, APR, 17)] = name + " (Observed)" 1570 1571 # Patriots' Day 1572 if self.state in ('ME', 'MA') and year >= 1969: 1573 self[date(year, APR, 1) + rd(weekday=MO(+3))] = "Patriots' Day" 1574 elif self.state in ('ME', 'MA') and year >= 1894: 1575 self[date(year, APR, 19)] = "Patriots' Day" 1576 1577 # Holy Thursday 1578 if self.state == 'VI': 1579 self[easter(year) + rd(weekday=TH(-1))] = "Holy Thursday" 1580 1581 # Good Friday 1582 if self.state in ('CT', 'DE', 'GU', 'IN', 'KY', 'LA', 1583 'NJ', 'NC', 'PR', 'TN', 'TX', 'VI'): 1584 self[easter(year) + rd(weekday=FR(-1))] = "Good Friday" 1585 1586 # Easter Monday 1587 if self.state == 'VI': 1588 self[easter(year) + rd(weekday=MO)] = "Easter Monday" 1589 1590 # Confederate Memorial Day 1591 name = "Confederate Memorial Day" 1592 if self.state in ('AL', 'GA', 'MS', 'SC') and year >= 1866: 1593 if self.state == 'GA' and year >= 2016: 1594 name = "State Holiday" 1595 self[date(year, APR, 1) + rd(weekday=MO(+4))] = name 1596 elif self.state == 'TX' and year >= 1931: 1597 self[date(year, JAN, 19)] = name 1598 1599 # San Jacinto Day 1600 if self.state == 'TX' and year >= 1875: 1601 self[date(year, APR, 21)] = "San Jacinto Day" 1602 1603 # Arbor Day 1604 if self.state == 'NE' and year >= 1989: 1605 self[date(year, APR, 30) + rd(weekday=FR(-1))] = "Arbor Day" 1606 elif self.state == 'NE' and year >= 1875: 1607 self[date(year, APR, 22)] = "Arbor Day" 1608 1609 # Primary Election Day 1610 if self.state == 'IN' and \ 1611 ((year >= 2006 and year % 2 == 0) or year >= 2015): 1612 dt = date(year, MAY, 1) + rd(weekday=MO) 1613 self[dt + rd(days=+1)] = "Primary Election Day" 1614 1615 # Truman Day 1616 if self.state == 'MO' and year >= 1949: 1617 name = "Truman Day" 1618 self[date(year, MAY, 8)] = name 1619 if self.observed and date(year, MAY, 8).weekday() == SAT: 1620 self[date(year, MAY, 7)] = name + " (Observed)" 1621 elif self.observed and date(year, MAY, 8).weekday() == SUN: 1622 self[date(year, MAY, 10)] = name + " (Observed)" 1623 1624 # Memorial Day 1625 if year > 1970: 1626 self[date(year, MAY, 31) + rd(weekday=MO(-1))] = "Memorial Day" 1627 elif year >= 1888: 1628 self[date(year, MAY, 30)] = "Memorial Day" 1629 1630 # Jefferson Davis Birthday 1631 name = "Jefferson Davis Birthday" 1632 if self.state == 'AL' and year >= 1890: 1633 self[date(year, JUN, 1) + rd(weekday=MO)] = name 1634 1635 # Kamehameha Day 1636 if self.state == 'HI' and year >= 1872: 1637 self[date(year, JUN, 11)] = "Kamehameha Day" 1638 if self.observed and year >= 2011: 1639 if date(year, JUN, 11).weekday() == SAT: 1640 self[date(year, JUN, 10)] = "Kamehameha Day (Observed)" 1641 elif date(year, JUN, 11).weekday() == SUN: 1642 self[date(year, JUN, 12)] = "Kamehameha Day (Observed)" 1643 1644 # Emancipation Day In Texas 1645 if self.state == 'TX' and year >= 1980: 1646 self[date(year, JUN, 19)] = "Emancipation Day In Texas" 1647 1648 # West Virginia Day 1649 name = "West Virginia Day" 1650 if self.state == 'WV' and year >= 1927: 1651 self[date(year, JUN, 20)] = name 1652 if self.observed and date(year, JUN, 20).weekday() == SAT: 1653 self[date(year, JUN, 19)] = name + " (Observed)" 1654 elif self.observed and date(year, JUN, 20).weekday() == SUN: 1655 self[date(year, JUN, 21)] = name + " (Observed)" 1656 1657 # Emancipation Day in US Virgin Islands 1658 if self.state == 'VI': 1659 self[date(year, JUL, 3)] = "Emancipation Day" 1660 1661 # Independence Day 1662 if year > 1870: 1663 name = "Independence Day" 1664 self[date(year, JUL, 4)] = name 1665 if self.observed and date(year, JUL, 4).weekday() == SAT: 1666 self[date(year, JUL, 4) + rd(days=-1)] = name + " (Observed)" 1667 elif self.observed and date(year, JUL, 4).weekday() == SUN: 1668 self[date(year, JUL, 4) + rd(days=+1)] = name + " (Observed)" 1669 1670 # Liberation Day (Guam) 1671 if self.state == 'GU' and year >= 1945: 1672 self[date(year, JUL, 21)] = "Liberation Day (Guam)" 1673 1674 # Pioneer Day 1675 if self.state == 'UT' and year >= 1849: 1676 name = "Pioneer Day" 1677 self[date(year, JUL, 24)] = name 1678 if self.observed and date(year, JUL, 24).weekday() == SAT: 1679 self[date(year, JUL, 24) + rd(days=-1)] = name + " (Observed)" 1680 elif self.observed and date(year, JUL, 24).weekday() == SUN: 1681 self[date(year, JUL, 24) + rd(days=+1)] = name + " (Observed)" 1682 1683 # Constitution Day 1684 if self.state == 'PR': 1685 self[date(year, JUL, 25)] = "Constitution Day" 1686 if self.observed and date(year, JUL, 25).weekday() == SUN: 1687 self[date(year, JUL, 26)] = "Constitution Day (Observed)" 1688 1689 # Victory Day 1690 if self.state == 'RI' and year >= 1948: 1691 self[date(year, AUG, 1) + rd(weekday=MO(+2))] = "Victory Day" 1692 1693 # Statehood Day (Hawaii) 1694 if self.state == 'HI' and year >= 1959: 1695 self[date(year, AUG, 1) + rd(weekday=FR(+3))] = "Statehood Day" 1696 1697 # Bennington Battle Day 1698 if self.state == 'VT' and year >= 1778: 1699 name = "Bennington Battle Day" 1700 self[date(year, AUG, 16)] = name 1701 if self.observed and date(year, AUG, 16).weekday() == SAT: 1702 self[date(year, AUG, 15)] = name + " (Observed)" 1703 elif self.observed and date(year, AUG, 16).weekday() == SUN: 1704 self[date(year, AUG, 17)] = name + " (Observed)" 1705 1706 # Lyndon Baines Johnson Day 1707 if self.state == 'TX' and year >= 1973: 1708 self[date(year, AUG, 27)] = "Lyndon Baines Johnson Day" 1709 1710 # Labor Day 1711 if year >= 1894: 1712 self[date(year, SEP, 1) + rd(weekday=MO)] = "Labor Day" 1713 1714 # Columbus Day 1715 if self.state not in ('AK', 'AR', 'DE', 'FL', 'HI', 'NV'): 1716 if self.state == 'SD': 1717 name = "Native American Day" 1718 elif self.state == 'VI': 1719 name = "Columbus Day and Puerto Rico Friendship Day" 1720 else: 1721 name = "Columbus Day" 1722 if year >= 1970: 1723 self[date(year, OCT, 1) + rd(weekday=MO(+2))] = name 1724 elif year >= 1937: 1725 self[date(year, OCT, 12)] = name 1726 1727 # Alaska Day 1728 if self.state == 'AK' and year >= 1867: 1729 self[date(year, OCT, 18)] = "Alaska Day" 1730 if self.observed \ 1731 and date(year, OCT, 18).weekday() == SAT: 1732 self[date(year, OCT, 18) + rd(days=-1)] = name + \ 1733 " (Observed)" 1734 elif self.observed \ 1735 and date(year, OCT, 18).weekday() == SUN: 1736 self[date(year, OCT, 18) + rd(days=+1)] = name + \ 1737 " (Observed)" 1738 1739 # Nevada Day 1740 if self.state == 'NV' and year >= 1933: 1741 dt = date(year, OCT, 31) 1742 if year >= 2000: 1743 dt += rd(weekday=FR(-1)) 1744 self[dt] = "Nevada Day" 1745 if self.observed and dt.weekday() == SAT: 1746 self[dt + rd(days=-1)] = "Nevada Day (Observed)" 1747 elif self.observed and dt.weekday() == SUN: 1748 self[dt + rd(days=+1)] = "Nevada Day (Observed)" 1749 1750 # Liberty Day 1751 if self.state == 'VI': 1752 self[date(year, NOV, 1)] = "Liberty Day" 1753 1754 # Election Day 1755 if (self.state in ('DE', 'HI', 'IL', 'IN', 'LA', 1756 'MT', 'NH', 'NJ', 'NY', 'WV') and 1757 year >= 2008 and year % 2 == 0) \ 1758 or (self.state in ('IN', 'NY') and year >= 2015): 1759 dt = date(year, NOV, 1) + rd(weekday=MO) 1760 self[dt + rd(days=+1)] = "Election Day" 1761 1762 # All Souls' Day 1763 if self.state == 'GU': 1764 self[date(year, NOV, 2)] = "All Souls' Day" 1765 1766 # Veterans Day 1767 if year > 1953: 1768 name = "Veterans Day" 1769 else: 1770 name = "Armistice Day" 1771 if 1978 > year > 1970: 1772 self[date(year, OCT, 1) + rd(weekday=MO(+4))] = name 1773 elif year >= 1938: 1774 self[date(year, NOV, 11)] = name 1775 if self.observed \ 1776 and date(year, NOV, 11).weekday() == SAT: 1777 self[date(year, NOV, 11) + rd(days=-1)] = name + \ 1778 " (Observed)" 1779 elif self.observed \ 1780 and date(year, NOV, 11).weekday() == SUN: 1781 self[date(year, NOV, 11) + rd(days=+1)] = name + \ 1782 " (Observed)" 1783 1784 # Discovery Day 1785 if self.state == 'PR': 1786 self[date(year, NOV, 19)] = "Discovery Day" 1787 if self.observed and date(year, NOV, 19).weekday() == SUN: 1788 self[date(year, NOV, 20)] = "Discovery Day (Observed)" 1789 1790 # Thanksgiving 1791 if year > 1870: 1792 self[date(year, NOV, 1) + rd(weekday=TH(+4))] = "Thanksgiving" 1793 1794 # Day After Thanksgiving 1795 # Friday After Thanksgiving 1796 # Lincoln's Birthday 1797 # American Indian Heritage Day 1798 # Family Day 1799 # New Mexico Presidents' Day 1800 if (self.state in ('DE', 'FL', 'NH', 'NC', 'OK', 'TX', 'WV') and 1801 year >= 1975) \ 1802 or (self.state == 'IN' and year >= 2010) \ 1803 or (self.state == 'MD' and year >= 2008) \ 1804 or self.state in ('NV', 'NM'): 1805 if self.state in ('DE', 'NH', 'NC', 'OK', 'WV'): 1806 name = "Day After Thanksgiving" 1807 elif self.state in ('FL', 'TX'): 1808 name = "Friday After Thanksgiving" 1809 elif self.state == 'IN': 1810 name = "Lincoln's Birthday" 1811 elif self.state == 'MD' and year >= 2008: 1812 name = "American Indian Heritage Day" 1813 elif self.state == 'NV': 1814 name = "Family Day" 1815 elif self.state == 'NM': 1816 name = "Presidents' Day" 1817 dt = date(year, NOV, 1) + rd(weekday=TH(+4)) 1818 self[dt + rd(days=+1)] = name 1819 1820 # Robert E. Lee's Birthday 1821 if self.state == 'GA' and year >= 1986: 1822 if year >= 2016: 1823 name = "State Holiday" 1824 else: 1825 name = "Robert E. Lee's Birthday" 1826 self[date(year, NOV, 29) + rd(weekday=FR(-1))] = name 1827 1828 # Lady of Camarin Day 1829 if self.state == 'GU': 1830 self[date(year, DEC, 8)] = "Lady of Camarin Day" 1831 1832 # Christmas Eve 1833 if self.state == 'AS' or \ 1834 (self.state in ('KS', 'MI', 'NC') and year >= 2013) or \ 1835 (self.state == 'TX' and year >= 1981) or \ 1836 (self.state == 'WI' and year >= 2012): 1837 name = "Christmas Eve" 1838 self[date(year, DEC, 24)] = name 1839 name = name + " (Observed)" 1840 # If on Friday, observed on Thursday 1841 if self.observed and date(year, DEC, 24).weekday() == FRI: 1842 self[date(year, DEC, 24) + rd(days=-1)] = name 1843 # If on Saturday or Sunday, observed on Friday 1844 elif self.observed \ 1845 and date(year, DEC, 24).weekday() in WEEKEND: 1846 self[date(year, DEC, 24) + rd(weekday=FR(-1))] = name 1847 1848 # Christmas Day 1849 if year > 1870: 1850 name = "Christmas Day" 1851 self[date(year, DEC, 25)] = "Christmas Day" 1852 if self.observed \ 1853 and date(year, DEC, 25).weekday() == SAT: 1854 self[date(year, DEC, 25) + rd(days=-1)] = name + \ 1855 " (Observed)" 1856 elif self.observed \ 1857 and date(year, DEC, 25).weekday() == SUN: 1858 self[date(year, DEC, 25) + rd(days=+1)] = name + \ 1859 " (Observed)" 1860 1861 # Day After Christmas 1862 if self.state == 'NC' and year >= 2013: 1863 name = "Day After Christmas" 1864 self[date(year, DEC, 26)] = name 1865 name = name + " (Observed)" 1866 # If on Saturday or Sunday, observed on Monday 1867 if self.observed and date(year, DEC, 26).weekday() in WEEKEND: 1868 self[date(year, DEC, 26) + rd(weekday=MO)] = name 1869 # If on Monday, observed on Tuesday 1870 elif self.observed \ 1871 and date(year, DEC, 26).weekday() == MON: 1872 self[date(year, DEC, 26) + rd(days=+1)] = name 1873 elif self.state == 'TX' and year >= 1981: 1874 self[date(year, DEC, 26)] = "Day After Christmas" 1875 elif self.state == 'VI': 1876 self[date(year, DEC, 26)] = "Christmas Second Day" 1877 1878 # New Year's Eve 1879 if (self.state in ('KY', 'MI') and year >= 2013) or \ 1880 (self.state == 'WI' and year >= 2012): 1881 name = "New Year's Eve" 1882 self[date(year, DEC, 31)] = name 1883 if self.observed \ 1884 and date(year, DEC, 31).weekday() == SAT: 1885 self[date(year, DEC, 30)] = name + " (Observed)" 1886 1887 1888class US(UnitedStates): 1889 pass 1890 1891 1892class NewZealand(HolidayBase): 1893 PROVINCES = ['NTL', 'AUK', 'TKI', 'HKB', 'WGN', 'MBH', 'NSN', 'CAN', 1894 'STC', 'WTL', 'OTA', 'STL', 'CIT'] 1895 1896 def __init__(self, **kwargs): 1897 self.country = 'NZ' 1898 HolidayBase.__init__(self, **kwargs) 1899 1900 def _populate(self, year): 1901 # Bank Holidays Act 1873 1902 # The Employment of Females Act 1873 1903 # Factories Act 1894 1904 # Industrial Conciliation and Arbitration Act 1894 1905 # Labour Day Act 1899 1906 # Anzac Day Act 1920, 1949, 1956 1907 # New Zealand Day Act 1973 1908 # Waitangi Day Act 1960, 1976 1909 # Sovereign's Birthday Observance Act 1937, 1952 1910 # Holidays Act 1981, 2003 1911 if year < 1894: 1912 return 1913 1914 # New Year's Day 1915 name = "New Year's Day" 1916 jan1 = date(year, JAN, 1) 1917 self[jan1] = name 1918 if self.observed and jan1.weekday() in WEEKEND: 1919 self[date(year, JAN, 3)] = name + " (Observed)" 1920 1921 name = "Day after New Year's Day" 1922 jan2 = date(year, JAN, 2) 1923 self[jan2] = name 1924 if self.observed and jan2.weekday() in WEEKEND: 1925 self[date(year, JAN, 4)] = name + " (Observed)" 1926 1927 # Waitangi Day 1928 if year > 1973: 1929 name = "New Zealand Day" 1930 if year > 1976: 1931 name = "Waitangi Day" 1932 feb6 = date(year, FEB, 6) 1933 self[feb6] = name 1934 if self.observed and year >= 2014 and feb6.weekday() in WEEKEND: 1935 self[feb6 + rd(weekday=MO)] = name + " (Observed)" 1936 1937 # Easter 1938 self[easter(year) + rd(weekday=FR(-1))] = "Good Friday" 1939 self[easter(year) + rd(weekday=MO)] = "Easter Monday" 1940 1941 # Anzac Day 1942 if year > 1920: 1943 name = "Anzac Day" 1944 apr25 = date(year, APR, 25) 1945 self[apr25] = name 1946 if self.observed and year >= 2014 and apr25.weekday() in WEEKEND: 1947 self[apr25 + rd(weekday=MO)] = name + " (Observed)" 1948 1949 # Sovereign's Birthday 1950 if year >= 1952: 1951 name = "Queen's Birthday" 1952 elif year > 1901: 1953 name = "King's Birthday" 1954 if year == 1952: 1955 self[date(year, JUN, 2)] = name # Elizabeth II 1956 elif year > 1937: 1957 self[date(year, JUN, 1) + rd(weekday=MO(+1))] = name # EII & GVI 1958 elif year == 1937: 1959 self[date(year, JUN, 9)] = name # George VI 1960 elif year == 1936: 1961 self[date(year, JUN, 23)] = name # Edward VIII 1962 elif year > 1911: 1963 self[date(year, JUN, 3)] = name # George V 1964 elif year > 1901: 1965 # http://paperspast.natlib.govt.nz/cgi-bin/paperspast?a=d&d=NZH19091110.2.67 1966 self[date(year, NOV, 9)] = name # Edward VII 1967 1968 # Labour Day 1969 name = "Labour Day" 1970 if year >= 1910: 1971 self[date(year, OCT, 1) + rd(weekday=MO(+4))] = name 1972 elif year > 1899: 1973 self[date(year, OCT, 1) + rd(weekday=WE(+2))] = name 1974 1975 # Christmas Day 1976 name = "Christmas Day" 1977 dec25 = date(year, DEC, 25) 1978 self[dec25] = name 1979 if self.observed and dec25.weekday() in WEEKEND: 1980 self[date(year, DEC, 27)] = name + " (Observed)" 1981 1982 # Boxing Day 1983 name = "Boxing Day" 1984 dec26 = date(year, DEC, 26) 1985 self[dec26] = name 1986 if self.observed and dec26.weekday() in WEEKEND: 1987 self[date(year, DEC, 28)] = name + " (Observed)" 1988 1989 # Province Anniversary Day 1990 if self.prov in ('NTL', 'Northland', 'AUK', 'Auckland'): 1991 if 1963 < year <= 1973 and self.prov in ('NTL', 'Northland'): 1992 name = "Waitangi Day" 1993 dt = date(year, FEB, 6) 1994 else: 1995 name = "Auckland Anniversary Day" 1996 dt = date(year, JAN, 29) 1997 if dt.weekday() in (TUE, WED, THU): 1998 self[dt + rd(weekday=MO(-1))] = name 1999 else: 2000 self[dt + rd(weekday=MO)] = name 2001 2002 elif self.prov in ('TKI', 'Taranaki', 'New Plymouth'): 2003 name = "Taranaki Anniversary Day" 2004 self[date(year, MAR, 1) + rd(weekday=MO(+2))] = name 2005 2006 elif self.prov in ('HKB', "Hawke's Bay"): 2007 name = "Hawke's Bay Anniversary Day" 2008 labour_day = date(year, OCT, 1) + rd(weekday=MO(+4)) 2009 self[labour_day + rd(weekday=FR(-1))] = name 2010 2011 elif self.prov in ('WGN', 'Wellington'): 2012 name = "Wellington Anniversary Day" 2013 jan22 = date(year, JAN, 22) 2014 if jan22.weekday() in (TUE, WED, THU): 2015 self[jan22 + rd(weekday=MO(-1))] = name 2016 else: 2017 self[jan22 + rd(weekday=MO)] = name 2018 2019 elif self.prov in ('MBH', 'Marlborough'): 2020 name = "Marlborough Anniversary Day" 2021 labour_day = date(year, OCT, 1) + rd(weekday=MO(+4)) 2022 self[labour_day + rd(weeks=1)] = name 2023 2024 elif self.prov in ('NSN', 'Nelson'): 2025 name = "Nelson Anniversary Day" 2026 feb1 = date(year, FEB, 1) 2027 if feb1.weekday() in (TUE, WED, THU): 2028 self[feb1 + rd(weekday=MO(-1))] = name 2029 else: 2030 self[feb1 + rd(weekday=MO)] = name 2031 2032 elif self.prov in ('CAN', 'Canterbury'): 2033 name = "Canterbury Anniversary Day" 2034 showday = date(year, NOV, 1) + rd(weekday=TU) + \ 2035 rd(weekday=FR(+2)) 2036 self[showday] = name 2037 2038 elif self.prov in ('STC', 'South Canterbury'): 2039 name = "South Canterbury Anniversary Day" 2040 dominion_day = date(year, SEP, 1) + rd(weekday=MO(4)) 2041 self[dominion_day] = name 2042 2043 elif self.prov in ('WTL', 'Westland'): 2044 name = "Westland Anniversary Day" 2045 dec1 = date(year, DEC, 1) 2046 # Observance varies?!?! 2047 if year == 2005: # special case?!?! 2048 self[date(year, DEC, 5)] = name 2049 elif dec1.weekday() in (TUE, WED, THU): 2050 self[dec1 + rd(weekday=MO(-1))] = name 2051 else: 2052 self[dec1 + rd(weekday=MO)] = name 2053 2054 elif self.prov in ('OTA', 'Otago'): 2055 name = "Otago Anniversary Day" 2056 mar23 = date(year, MAR, 23) 2057 # there is no easily determined single day of local observance?!?! 2058 if mar23.weekday() in (TUE, WED, THU): 2059 dt = mar23 + rd(weekday=MO(-1)) 2060 else: 2061 dt = mar23 + rd(weekday=MO) 2062 if dt == easter(year) + rd(weekday=MO): # Avoid Easter Monday 2063 dt += rd(days=1) 2064 self[dt] = name 2065 2066 elif self.prov in ('STL', 'Southland'): 2067 name = "Southland Anniversary Day" 2068 jan17 = date(year, JAN, 17) 2069 if year > 2011: 2070 self[easter(year) + rd(weekday=TU)] = name 2071 else: 2072 if jan17.weekday() in (TUE, WED, THU): 2073 self[jan17 + rd(weekday=MO(-1))] = name 2074 else: 2075 self[jan17 + rd(weekday=MO)] = name 2076 2077 elif self.prov in ('CIT', 'Chatham Islands'): 2078 name = "Chatham Islands Anniversary Day" 2079 nov30 = date(year, NOV, 30) 2080 if nov30.weekday() in (TUE, WED, THU): 2081 self[nov30 + rd(weekday=MO(-1))] = name 2082 else: 2083 self[nov30 + rd(weekday=MO)] = name 2084 2085 2086class NZ(NewZealand): 2087 pass 2088 2089 2090class Australia(HolidayBase): 2091 PROVINCES = ['ACT', 'NSW', 'NT', 'QLD', 'SA', 'TAS', 'VIC', 'WA'] 2092 2093 def __init__(self, **kwargs): 2094 self.country = 'AU' 2095 self.prov = kwargs.pop('prov', None) 2096 HolidayBase.__init__(self, **kwargs) 2097 2098 def _populate(self, year): 2099 # ACT: Holidays Act 1958 2100 # NSW: Public Holidays Act 2010 2101 # NT: Public Holidays Act 2013 2102 # QLD: Holidays Act 1983 2103 # SA: Holidays Act 1910 2104 # TAS: Statutory Holidays Act 2000 2105 # VIC: Public Holidays Act 1993 2106 # WA: Public and Bank Holidays Act 1972 2107 2108 # TODO do more research on history of Aus holidays 2109 2110 # New Year's Day 2111 name = "New Year's Day" 2112 jan1 = date(year, JAN, 1) 2113 self[jan1] = name 2114 if self.observed and jan1.weekday() in WEEKEND: 2115 self[jan1 + rd(weekday=MO)] = name + " (Observed)" 2116 2117 # Australia Day 2118 jan26 = date(year, JAN, 26) 2119 if year >= 1935: 2120 if self.prov == 'NSW' and year < 1946: 2121 name = "Anniversary Day" 2122 else: 2123 name = "Australia Day" 2124 self[jan26] = name 2125 if self.observed and year >= 1946 and jan26.weekday() in WEEKEND: 2126 self[jan26 + rd(weekday=MO)] = name + " (Observed)" 2127 elif year >= 1888 and self.prov != 'SA': 2128 name = "Anniversary Day" 2129 self[jan26] = name 2130 2131 # Adelaide Cup 2132 if self.prov == 'SA': 2133 name = "Adelaide Cup" 2134 if year >= 2006: 2135 # subject to proclamation ?!?! 2136 self[date(year, MAR, 1) + rd(weekday=MO(+2))] = name 2137 else: 2138 self[date(year, MAR, 1) + rd(weekday=MO(+3))] = name 2139 2140 # Canberra Day 2141 # Info from https://www.timeanddate.com/holidays/australia/canberra-day 2142 # and https://en.wikipedia.org/wiki/Canberra_Day 2143 if self.prov == 'ACT' and year >= 1913: 2144 name = "Canberra Day" 2145 if year >= 1913 and year <= 1957: 2146 self[date(year, MAR, 12)] = name 2147 elif year >= 1958 and year <= 2007: 2148 self[date(year, MAR, 1) + rd(weekday=MO(+3))] = name 2149 elif year >= 2008 and year != 2012: 2150 self[date(year, MAR, 1) + rd(weekday=MO(+2))] = name 2151 elif year == 2012: 2152 self[date(year, MAR, 12)] = name 2153 2154 # Easter 2155 self[easter(year) + rd(weekday=FR(-1))] = "Good Friday" 2156 if self.prov in ('ACT', 'NSW', 'NT', 'QLD', 'SA', 'VIC'): 2157 self[easter(year) + rd(weekday=SA(-1))] = "Easter Saturday" 2158 if self.prov in ('ACT', 'NSW', 'QLD', 'VIC'): 2159 self[easter(year)] = "Easter Sunday" 2160 self[easter(year) + rd(weekday=MO)] = "Easter Monday" 2161 2162 # Anzac Day 2163 if year > 1920: 2164 name = "Anzac Day" 2165 apr25 = date(year, APR, 25) 2166 self[apr25] = name 2167 if self.observed: 2168 if apr25.weekday() == SAT and self.prov in ('WA', 'NT'): 2169 self[apr25 + rd(weekday=MO)] = name + " (Observed)" 2170 elif (apr25.weekday() == SUN and 2171 self.prov in ('ACT', 'QLD', 'SA', 'WA', 'NT')): 2172 self[apr25 + rd(weekday=MO)] = name + " (Observed)" 2173 2174 # Western Australia Day 2175 if self.prov == 'WA' and year > 1832: 2176 if year >= 2015: 2177 name = "Western Australia Day" 2178 else: 2179 name = "Foundation Day" 2180 self[date(year, JUN, 1) + rd(weekday=MO(+1))] = name 2181 2182 # Sovereign's Birthday 2183 if year >= 1952: 2184 name = "Queen's Birthday" 2185 elif year > 1901: 2186 name = "King's Birthday" 2187 if year >= 1936: 2188 name = "Queen's Birthday" 2189 if self.prov == 'QLD': 2190 if year == 2012: 2191 self[date(year, JUN, 11)] = "Queen's Diamond Jubilee" 2192 if year < 2016 and year != 2012: 2193 dt = date(year, JUN, 1) + rd(weekday=MO(+2)) 2194 self[dt] = name 2195 else: 2196 dt = date(year, OCT, 1) + rd(weekday=MO) 2197 self[dt] = name 2198 elif self.prov == 'WA': 2199 # by proclamation ?!?! 2200 self[date(year, OCT, 1) + rd(weekday=MO(-1))] = name 2201 elif self.prov in ('NSW', 'VIC', 'ACT', 'SA', 'NT', 'TAS'): 2202 dt = date(year, JUN, 1) + rd(weekday=MO(+2)) 2203 self[dt] = name 2204 elif year > 1911: 2205 self[date(year, JUN, 3)] = name # George V 2206 elif year > 1901: 2207 self[date(year, NOV, 9)] = name # Edward VII 2208 2209 # Picnic Day 2210 if self.prov == 'NT': 2211 name = "Picnic Day" 2212 self[date(year, AUG, 1) + rd(weekday=MO)] = name 2213 2214 # Bank Holiday 2215 if self.prov == 'NSW': 2216 if year >= 1912: 2217 name = "Bank Holiday" 2218 self[date(year, 8, 1) + rd(weekday=MO)] = name 2219 2220 # Labour Day 2221 name = "Labour Day" 2222 if self.prov in ('NSW', 'ACT', 'SA'): 2223 self[date(year, OCT, 1) + rd(weekday=MO)] = name 2224 elif self.prov == 'WA': 2225 self[date(year, MAR, 1) + rd(weekday=MO)] = name 2226 elif self.prov == 'VIC': 2227 self[date(year, MAR, 1) + rd(weekday=MO(+2))] = name 2228 elif self.prov == 'QLD': 2229 if 2013 <= year <= 2015: 2230 self[date(year, OCT, 1) + rd(weekday=MO)] = name 2231 else: 2232 self[date(year, MAY, 1) + rd(weekday=MO)] = name 2233 elif self.prov == 'NT': 2234 name = "May Day" 2235 self[date(year, MAY, 1) + rd(weekday=MO)] = name 2236 elif self.prov == 'TAS': 2237 name = "Eight Hours Day" 2238 self[date(year, MAR, 1) + rd(weekday=MO(+2))] = name 2239 2240 # Family & Community Day 2241 if self.prov == 'ACT': 2242 name = "Family & Community Day" 2243 if 2007 <= year <= 2009: 2244 self[date(year, NOV, 1) + rd(weekday=TU)] = name 2245 elif year == 2010: 2246 # first Monday of the September/October school holidays 2247 # moved to the second Monday if this falls on Labour day 2248 # TODO need a formula for the ACT school holidays then 2249 # http://www.cmd.act.gov.au/communication/holidays 2250 self[date(year, SEP, 26)] = name 2251 elif year == 2011: 2252 self[date(year, OCT, 10)] = name 2253 elif year == 2012: 2254 self[date(year, OCT, 8)] = name 2255 elif year == 2013: 2256 self[date(year, SEP, 30)] = name 2257 elif year == 2014: 2258 self[date(year, SEP, 29)] = name 2259 elif year == 2015: 2260 self[date(year, SEP, 28)] = name 2261 elif year == 2016: 2262 self[date(year, SEP, 26)] = name 2263 elif year == 2017: 2264 self[date(year, SEP, 25)] = name 2265 2266 # Reconciliation Day 2267 if self.prov == 'ACT': 2268 name = "Reconciliation Day" 2269 if year >= 2018: 2270 self[date(year, 5, 27) + rd(weekday=MO)] = name 2271 2272 if self.prov == 'VIC': 2273 # Grand Final Day 2274 if year >= 2015: 2275 self[date(year, SEP, 24) + rd(weekday=FR)] = "Grand Final Day" 2276 2277 # Melbourne Cup 2278 self[date(year, NOV, 1) + rd(weekday=TU)] = "Melbourne Cup" 2279 2280 # The Royal Queensland Show (Ekka) 2281 # The Show starts on the first Friday of August - providing this is 2282 # not prior to the 5th - in which case it will begin on the second 2283 # Friday. The Wednesday during the show is a public holiday. 2284 if self.prov == 'QLD': 2285 name = "The Royal Queensland Show" 2286 self[date(year, AUG, 5) + rd(weekday=FR) + rd(weekday=WE)] = \ 2287 name 2288 2289 # Christmas Day 2290 name = "Christmas Day" 2291 dec25 = date(year, DEC, 25) 2292 self[dec25] = name 2293 if self.observed and dec25.weekday() in WEEKEND: 2294 self[date(year, DEC, 27)] = name + " (Observed)" 2295 2296 # Boxing Day 2297 if self.prov == 'SA': 2298 name = "Proclamation Day" 2299 else: 2300 name = "Boxing Day" 2301 dec26 = date(year, DEC, 26) 2302 self[dec26] = name 2303 if self.observed and dec26.weekday() in WEEKEND: 2304 self[date(year, DEC, 28)] = name + " (Observed)" 2305 2306 2307class AU(Australia): 2308 pass 2309 2310 2311class Germany(HolidayBase): 2312 """Official holidays for Germany in its current form. 2313 2314 This class doesn't return any holidays before 1990-10-03. 2315 2316 Before that date the current Germany was separated into the "German 2317 Democratic Republic" and the "Federal Republic of Germany" which both had 2318 somewhat different holidays. Since this class is called "Germany" it 2319 doesn't really make sense to include the days from the two former 2320 countries. 2321 2322 Note that Germany doesn't have rules for holidays that happen on a 2323 Sunday. Those holidays are still holiday days but there is no additional 2324 day to make up for the "lost" day. 2325 2326 Also note that German holidays are partly declared by each province there 2327 are some weired edge cases: 2328 2329 - "Mariä Himmelfahrt" is only a holiday in Bavaria (BY) if your 2330 municipality is mostly catholic which in term depends on census data. 2331 Since we don't have this data but most municipalities in Bavaria 2332 *are* mostly catholic, we count that as holiday for whole Bavaria. 2333 - There is an "Augsburger Friedensfest" which only exists in the town 2334 Augsburg. This is excluded for Bavaria. 2335 - "Gründonnerstag" (Thursday before easter) is not a holiday but pupil 2336 don't have to go to school (but only in Baden Württemberg) which is 2337 solved by adjusting school holidays to include this day. It is 2338 excluded from our list. 2339 - "Fronleichnam" is a holiday in certain, explicitly defined 2340 municipalities in Saxony (SN) and Thuringia (TH). We exclude it from 2341 both provinces. 2342 """ 2343 2344 PROVINCES = ['BW', 'BY', 'BE', 'BB', 'HB', 'HH', 'HE', 'MV', 'NI', 'NW', 2345 'RP', 'SL', 'SN', 'ST', 'SH', 'TH'] 2346 2347 def __init__(self, **kwargs): 2348 self.country = 'DE' 2349 self.prov = kwargs.pop('prov', None) 2350 HolidayBase.__init__(self, **kwargs) 2351 2352 def _populate(self, year): 2353 if year <= 1989: 2354 return 2355 2356 if year > 1990: 2357 2358 self[date(year, JAN, 1)] = 'Neujahr' 2359 2360 if self.prov in ('BW', 'BY', 'ST'): 2361 self[date(year, JAN, 6)] = 'Heilige Drei Könige' 2362 2363 self[easter(year) - rd(days=2)] = 'Karfreitag' 2364 2365 if self.prov == "BB": 2366 # will always be a Sunday and we have no "observed" rule so 2367 # this is pretty pointless but it's nonetheless an official 2368 # holiday by law 2369 self[easter(year)] = "Ostersonntag" 2370 2371 self[easter(year) + rd(days=1)] = 'Ostermontag' 2372 2373 self[date(year, MAY, 1)] = 'Erster Mai' 2374 2375 if self.prov == "BE" and year == 2020: 2376 self[date(year, MAY, 8)] = \ 2377 "75. Jahrestag der Befreiung vom Nationalsozialismus " \ 2378 "und der Beendigung des Zweiten Weltkriegs in Europa" 2379 2380 self[easter(year) + rd(days=39)] = 'Christi Himmelfahrt' 2381 2382 if self.prov == "BB": 2383 # will always be a Sunday and we have no "observed" rule so 2384 # this is pretty pointless but it's nonetheless an official 2385 # holiday by law 2386 self[easter(year) + rd(days=49)] = "Pfingstsonntag" 2387 2388 self[easter(year) + rd(days=50)] = 'Pfingstmontag' 2389 2390 if self.prov in ('BW', 'BY', 'HE', 'NW', 'RP', 'SL'): 2391 self[easter(year) + rd(days=60)] = 'Fronleichnam' 2392 2393 if self.prov in ('BY', 'SL'): 2394 self[date(year, AUG, 15)] = 'Mariä Himmelfahrt' 2395 2396 self[date(year, OCT, 3)] = 'Tag der Deutschen Einheit' 2397 2398 if self.prov in ('BB', 'MV', 'SN', 'ST', 'TH'): 2399 self[date(year, OCT, 31)] = 'Reformationstag' 2400 2401 if self.prov in ('HB', 'SH', 'NI', 'HH') and year >= 2018: 2402 self[date(year, OCT, 31)] = 'Reformationstag' 2403 2404 # in 2017 all states got the Reformationstag (500th anniversary of 2405 # Luther's thesis) 2406 if year == 2017: 2407 self[date(year, OCT, 31)] = 'Reformationstag' 2408 2409 if self.prov in ('BW', 'BY', 'NW', 'RP', 'SL'): 2410 self[date(year, NOV, 1)] = 'Allerheiligen' 2411 2412 if year <= 1994 or self.prov == 'SN': 2413 # can be calculated as "last wednesday before year-11-23" which is 2414 # why we need to go back two wednesdays if year-11-23 happens to be 2415 # a wednesday 2416 base_data = date(year, NOV, 23) 2417 weekday_delta = WE(-2) if base_data.weekday() == 2 else WE(-1) 2418 self[base_data + rd(weekday=weekday_delta)] = 'Buß- und Bettag' 2419 2420 if year >= 2019: 2421 if self.prov == 'TH': 2422 self[date(year, SEP, 20)] = 'Weltkindertag' 2423 2424 if self.prov == 'BE': 2425 self[date(year, MAR, 8)] = 'Internationaler Frauentag' 2426 2427 self[date(year, DEC, 25)] = 'Erster Weihnachtstag' 2428 self[date(year, DEC, 26)] = 'Zweiter Weihnachtstag' 2429 2430 2431class DE(Germany): 2432 pass 2433 2434 2435class Austria(HolidayBase): 2436 PROVINCES = ['B', 'K', 'N', 'O', 'S', 'ST', 'T', 'V', 'W'] 2437 2438 def __init__(self, **kwargs): 2439 self.country = 'AT' 2440 self.prov = kwargs.pop('prov', kwargs.pop('state', 'W')) 2441 HolidayBase.__init__(self, **kwargs) 2442 2443 def _populate(self, year): 2444 # public holidays 2445 self[date(year, JAN, 1)] = "Neujahr" 2446 self[date(year, JAN, 6)] = "Heilige Drei Könige" 2447 self[easter(year) + rd(weekday=MO)] = "Ostermontag" 2448 self[date(year, MAY, 1)] = "Staatsfeiertag" 2449 self[easter(year) + rd(days=39)] = "Christi Himmelfahrt" 2450 self[easter(year) + rd(days=50)] = "Pfingstmontag" 2451 self[easter(year) + rd(days=60)] = "Fronleichnam" 2452 self[date(year, AUG, 15)] = "Mariä Himmelfahrt" 2453 if 1919 <= year <= 1934: 2454 self[date(year, NOV, 12)] = "Nationalfeiertag" 2455 if year >= 1967: 2456 self[date(year, OCT, 26)] = "Nationalfeiertag" 2457 self[date(year, NOV, 1)] = "Allerheiligen" 2458 self[date(year, DEC, 8)] = "Mariä Empfängnis" 2459 self[date(year, DEC, 25)] = "Christtag" 2460 self[date(year, DEC, 26)] = "Stefanitag" 2461 2462 2463class AT(Austria): 2464 pass 2465 2466 2467class Denmark(HolidayBase): 2468 # https://en.wikipedia.org/wiki/Public_holidays_in_Denmark 2469 2470 def __init__(self, **kwargs): 2471 self.country = 'DK' 2472 HolidayBase.__init__(self, **kwargs) 2473 2474 def _populate(self, year): 2475 # Public holidays 2476 self[date(year, JAN, 1)] = "Nytårsdag" 2477 self[easter(year) + rd(weekday=SU(-2))] = "Palmesøndag" 2478 self[easter(year) + rd(weekday=TH(-1))] = "Skærtorsdag" 2479 self[easter(year) + rd(weekday=FR(-1))] = "Langfredag" 2480 self[easter(year)] = "Påskedag" 2481 self[easter(year) + rd(weekday=MO)] = "Anden påskedag" 2482 self[easter(year) + rd(weekday=FR(+4))] = "Store bededag" 2483 self[easter(year) + rd(days=39)] = "Kristi himmelfartsdag" 2484 self[easter(year) + rd(days=49)] = "Pinsedag" 2485 self[easter(year) + rd(days=50)] = "Anden pinsedag" 2486 self[date(year, DEC, 25)] = "Juledag" 2487 self[date(year, DEC, 26)] = "Anden juledag" 2488 2489 2490class DK(Denmark): 2491 pass 2492 2493 2494class UnitedKingdom(HolidayBase): 2495 # https://en.wikipedia.org/wiki/Public_holidays_in_the_United_Kingdom 2496 2497 def __init__(self, **kwargs): 2498 self.country = 'UK' 2499 HolidayBase.__init__(self, **kwargs) 2500 2501 def _populate(self, year): 2502 2503 # New Year's Day 2504 if year >= 1974: 2505 name = "New Year's Day" 2506 self[date(year, JAN, 1)] = name 2507 if self.observed and date(year, JAN, 1).weekday() == SUN: 2508 self[date(year, JAN, 1) + rd(days=+1)] = name + \ 2509 " (Observed)" 2510 elif self.observed \ 2511 and date(year, JAN, 1).weekday() == SAT: 2512 self[date(year, JAN, 1) + rd(days=+2)] = name + \ 2513 " (Observed)" 2514 2515 # New Year Holiday 2516 if self.country in ('UK', 'Scotland'): 2517 name = "New Year Holiday" 2518 if self.country == 'UK': 2519 name += " [Scotland]" 2520 self[date(year, JAN, 2)] = name 2521 if self.observed and date(year, JAN, 2).weekday() in WEEKEND: 2522 self[date(year, JAN, 2) + rd(days=+2)] = name + \ 2523 " (Observed)" 2524 elif self.observed and date(year, JAN, 2).weekday() == MON: 2525 self[date(year, JAN, 2) + rd(days=+1)] = name + \ 2526 " (Observed)" 2527 2528 # St. Patrick's Day 2529 if self.country in ('UK', 'Northern Ireland', 'Ireland'): 2530 name = "St. Patrick's Day" 2531 if self.country == 'UK': 2532 name += " [Northern Ireland]" 2533 self[date(year, MAR, 17)] = name 2534 if self.observed and date(year, MAR, 17).weekday() in WEEKEND: 2535 self[date(year, MAR, 17) + rd(weekday=MO)] = name + \ 2536 " (Observed)" 2537 2538 # Good Friday 2539 if self.country != 'Ireland': 2540 self[easter(year) + rd(weekday=FR(-1))] = "Good Friday" 2541 2542 # Easter Monday 2543 if self.country != 'Scotland': 2544 name = "Easter Monday" 2545 if self.country == 'UK': 2546 name += " [England, Wales, Northern Ireland]" 2547 self[easter(year) + rd(weekday=MO)] = name 2548 2549 # May Day bank holiday (first Monday in May) 2550 if year >= 1978: 2551 name = "May Day" 2552 if year == 2020 and self.country != 'Ireland': 2553 # Moved to Friday to mark 75th anniversary of VE Day. 2554 self[date(year, MAY, 8)] = name 2555 else: 2556 if year == 1995: 2557 dt = date(year, MAY, 8) 2558 else: 2559 dt = date(year, MAY, 1) 2560 if dt.weekday() == MON: 2561 self[dt] = name 2562 elif dt.weekday() == TUE: 2563 self[dt + rd(days=+6)] = name 2564 elif dt.weekday() == WED: 2565 self[dt + rd(days=+5)] = name 2566 elif dt.weekday() == THU: 2567 self[dt + rd(days=+4)] = name 2568 elif dt.weekday() == FRI: 2569 self[dt + rd(days=+3)] = name 2570 elif dt.weekday() == SAT: 2571 self[dt + rd(days=+2)] = name 2572 elif dt.weekday() == SUN: 2573 self[dt + rd(days=+1)] = name 2574 2575 # Spring bank holiday (last Monday in May) 2576 if self.country != 'Ireland': 2577 name = "Spring Bank Holiday" 2578 if year == 2012: 2579 self[date(year, JUN, 4)] = name 2580 elif year >= 1971: 2581 self[date(year, MAY, 31) + rd(weekday=MO(-1))] = name 2582 2583 # June bank holiday (first Monday in June) 2584 if self.country == 'Ireland': 2585 self[date(year, JUN, 1) + rd(weekday=MO)] = "June Bank Holiday" 2586 2587 # TT bank holiday (first Friday in June) 2588 if self.country == 'Isle of Man': 2589 self[date(year, JUN, 1) + rd(weekday=FR)] = "TT Bank Holiday" 2590 2591 # Tynwald Day 2592 if self.country == 'Isle of Man': 2593 self[date(year, JUL, 5)] = "Tynwald Day" 2594 2595 # Battle of the Boyne 2596 if self.country in ('UK', 'Northern Ireland'): 2597 name = "Battle of the Boyne" 2598 if self.country == 'UK': 2599 name += " [Northern Ireland]" 2600 self[date(year, JUL, 12)] = name 2601 2602 # Summer bank holiday (first Monday in August) 2603 if self.country in ('UK', 'Scotland', 'Ireland'): 2604 name = "Summer Bank Holiday" 2605 if self.country == 'UK': 2606 name += " [Scotland]" 2607 self[date(year, AUG, 1) + rd(weekday=MO)] = name 2608 2609 # Late Summer bank holiday (last Monday in August) 2610 if self.country not in ('Scotland', 'Ireland') and year >= 1971: 2611 name = "Late Summer Bank Holiday" 2612 if self.country == 'UK': 2613 name += " [England, Wales, Northern Ireland]" 2614 self[date(year, AUG, 31) + rd(weekday=MO(-1))] = name 2615 2616 # October Bank Holiday (last Monday in October) 2617 if self.country == 'Ireland': 2618 name = "October Bank Holiday" 2619 self[date(year, OCT, 31) + rd(weekday=MO(-1))] = name 2620 2621 # St. Andrew's Day 2622 if self.country in ('UK', 'Scotland'): 2623 name = "St. Andrew's Day" 2624 if self.country == 'UK': 2625 name += " [Scotland]" 2626 self[date(year, NOV, 30)] = name 2627 2628 # Christmas Day 2629 name = "Christmas Day" 2630 self[date(year, DEC, 25)] = name 2631 if self.observed and date(year, DEC, 25).weekday() == SAT: 2632 self[date(year, DEC, 27)] = name + " (Observed)" 2633 elif self.observed and date(year, DEC, 25).weekday() == SUN: 2634 self[date(year, DEC, 27)] = name + " (Observed)" 2635 2636 # Boxing Day 2637 name = "Boxing Day" 2638 self[date(year, DEC, 26)] = name 2639 if self.observed and date(year, DEC, 26).weekday() == SAT: 2640 self[date(year, DEC, 28)] = name + " (Observed)" 2641 elif self.observed and date(year, DEC, 26).weekday() == SUN: 2642 self[date(year, DEC, 28)] = name + " (Observed)" 2643 2644 # Special holidays 2645 if self.country != 'Ireland': 2646 if year == 1977: 2647 self[date(year, JUN, 7)] = "Silver Jubilee of Elizabeth II" 2648 elif year == 1981: 2649 self[date(year, JUL, 29)] = "Wedding of Charles and Diana" 2650 elif year == 1999: 2651 self[date(year, DEC, 31)] = "Millennium Celebrations" 2652 elif year == 2002: 2653 self[date(year, JUN, 3)] = "Golden Jubilee of Elizabeth II" 2654 elif year == 2011: 2655 self[date(year, APR, 29)] = "Wedding of William and" \ 2656 " Catherine" 2657 elif year == 2012: 2658 self[date(year, JUN, 5)] = "Diamond Jubilee of Elizabeth II" 2659 2660 2661class UK(UnitedKingdom): 2662 pass 2663 2664 2665class GB(UnitedKingdom): 2666 pass 2667 2668 2669class England(UnitedKingdom): 2670 2671 def __init__(self, **kwargs): 2672 self.country = 'England' 2673 HolidayBase.__init__(self, **kwargs) 2674 2675 2676class Wales(UnitedKingdom): 2677 2678 def __init__(self, **kwargs): 2679 self.country = 'Wales' 2680 HolidayBase.__init__(self, **kwargs) 2681 2682 2683class Scotland(UnitedKingdom): 2684 2685 def __init__(self, **kwargs): 2686 self.country = 'Scotland' 2687 HolidayBase.__init__(self, **kwargs) 2688 2689 2690class IsleOfMan(UnitedKingdom): 2691 2692 def __init__(self, **kwargs): 2693 self.country = 'Isle of Man' 2694 HolidayBase.__init__(self, **kwargs) 2695 2696 2697class NorthernIreland(UnitedKingdom): 2698 2699 def __init__(self, **kwargs): 2700 self.country = 'Northern Ireland' 2701 HolidayBase.__init__(self, **kwargs) 2702 2703 2704class Ireland(UnitedKingdom): 2705 2706 def __init__(self, **kwargs): 2707 self.country = 'Ireland' 2708 HolidayBase.__init__(self, **kwargs) 2709 2710 2711class IE(Ireland): 2712 pass 2713 2714 2715class Spain(HolidayBase): 2716 PROVINCES = ['AND', 'ARG', 'AST', 'CAN', 'CAM', 'CAL', 'CAT', 'CVA', 2717 'EXT', 'GAL', 'IBA', 'ICA', 'MAD', 'MUR', 'NAV', 'PVA', 'RIO'] 2718 2719 def __init__(self, **kwargs): 2720 self.country = 'ES' 2721 self.prov = kwargs.pop('prov', kwargs.pop('state', '')) 2722 HolidayBase.__init__(self, **kwargs) 2723 2724 def _populate(self, year): 2725 self[date(year, JAN, 1)] = "Año nuevo" 2726 self[date(year, JAN, 6)] = "Epifanía del Señor" 2727 if self.prov and self.prov in ['CVA', 'MUR', 'MAD', 'NAV', 'PVA']: 2728 self[date(year, MAR, 19)] = "San José" 2729 if self.prov and self.prov != 'CAT': 2730 self[easter(year) + rd(weeks=-1, weekday=TH)] = "Jueves Santo" 2731 self[easter(year) + rd(weeks=-1, weekday=FR)] = "Viernes Santo" 2732 if self.prov and self.prov in ['CAT', 'PVA', 'NAV', 'CVA', 'IBA']: 2733 self[easter(year) + rd(weekday=MO)] = "Lunes de Pascua" 2734 self[date(year, MAY, 1)] = "Día del Trabajador" 2735 if self.prov and self.prov in ['CAT', 'GAL']: 2736 self[date(year, JUN, 24)] = "San Juan" 2737 self[date(year, AUG, 15)] = "Asunción de la Virgen" 2738 self[date(year, OCT, 12)] = "Día de la Hispanidad" 2739 self[date(year, NOV, 1)] = "Todos los Santos" 2740 self[date(year, DEC, 6)] = "Día de la constitución Española" 2741 self[date(year, DEC, 8)] = "La Inmaculada Concepción" 2742 self[date(year, DEC, 25)] = "Navidad" 2743 if self.prov and self.prov in ['CAT', 'IBA']: 2744 self[date(year, DEC, 26)] = "San Esteban" 2745 # Provinces festive day 2746 if self.prov: 2747 if self.prov == 'AND': 2748 self[date(year, FEB, 28)] = "Día de Andalucia" 2749 elif self.prov == 'ARG': 2750 self[date(year, APR, 23)] = "Día de San Jorge" 2751 elif self.prov == 'AST': 2752 self[date(year, MAR, 8)] = "Día de Asturias" 2753 elif self.prov == 'CAN': 2754 self[date(year, FEB, 28)] = "Día de la Montaña" 2755 elif self.prov == 'CAM': 2756 self[date(year, FEB, 28)] = "Día de Castilla - La Mancha" 2757 elif self.prov == 'CAL': 2758 self[date(year, APR, 23)] = "Día de Castilla y Leon" 2759 elif self.prov == 'CAT': 2760 self[date(year, SEP, 11)] = "Día Nacional de Catalunya" 2761 elif self.prov == 'CVA': 2762 self[date(year, OCT, 9)] = "Día de la Comunidad Valenciana" 2763 elif self.prov == 'EXT': 2764 self[date(year, SEP, 8)] = "Día de Extremadura" 2765 elif self.prov == 'GAL': 2766 self[date(year, JUL, 25)] = "Día Nacional de Galicia" 2767 elif self.prov == 'IBA': 2768 self[date(year, MAR, 1)] = "Día de las Islas Baleares" 2769 elif self.prov == 'ICA': 2770 self[date(year, MAY, 30)] = "Día de Canarias" 2771 elif self.prov == 'MAD': 2772 self[date(year, MAY, 2)] = "Día de Comunidad De Madrid" 2773 elif self.prov == 'MUR': 2774 self[date(year, JUN, 9)] = "Día de la Región de Murcia" 2775 elif self.prov == 'NAV': 2776 self[date(year, SEP, 27)] = "Día de Navarra" 2777 elif self.prov == 'PVA': 2778 self[date(year, OCT, 25)] = "Día del Páis Vasco" 2779 elif self.prov == 'RIO': 2780 self[date(year, JUN, 9)] = "Día de La Rioja" 2781 2782 2783class ES(Spain): 2784 pass 2785 2786 2787class EuropeanCentralBank(HolidayBase): 2788 # https://en.wikipedia.org/wiki/TARGET2 2789 # http://www.ecb.europa.eu/press/pr/date/2000/html/pr001214_4.en.html 2790 2791 def __init__(self, **kwargs): 2792 self.country = 'EU' 2793 HolidayBase.__init__(self, **kwargs) 2794 2795 def _populate(self, year): 2796 self[date(year, JAN, 1)] = "New Year's Day" 2797 e = easter(year) 2798 self[e - rd(days=2)] = "Good Friday" 2799 self[e + rd(days=1)] = "Easter Monday" 2800 self[date(year, MAY, 1)] = "1 May (Labour Day)" 2801 self[date(year, DEC, 25)] = "Christmas Day" 2802 self[date(year, DEC, 26)] = "26 December" 2803 2804 2805class ECB(EuropeanCentralBank): 2806 pass 2807 2808 2809class TAR(EuropeanCentralBank): 2810 pass 2811 2812 2813class Czechia(HolidayBase): 2814 # https://en.wikipedia.org/wiki/Public_holidays_in_the_Czech_Republic 2815 2816 def __init__(self, **kwargs): 2817 self.country = 'CZ' 2818 HolidayBase.__init__(self, **kwargs) 2819 2820 def _populate(self, year): 2821 self[date(year, JAN, 1)] = "Den obnovy samostatného českého" \ 2822 " státu" \ 2823 if year >= 2000 else \ 2824 "Nový rok" 2825 2826 e = easter(year) 2827 if year <= 1951 or year >= 2016: 2828 self[e - rd(days=2)] = "Velký pátek" 2829 self[e + rd(days=1)] = "Velikonoční pondělí" 2830 2831 if year >= 1951: 2832 self[date(year, MAY, 1)] = "Svátek práce" 2833 if year >= 1992: 2834 self[date(year, MAY, 8)] = "Den vítězství" 2835 elif year >= 1947: 2836 self[date(year, MAY, 9)] = "Den vítězství nad hitlerovským" \ 2837 " fašismem" 2838 if year >= 1951: 2839 self[date(year, JUL, 5)] = "Den slovanských věrozvěstů " \ 2840 "Cyrila a Metoděje" 2841 self[date(year, JUL, 6)] = "Den upálení mistra Jana Husa" 2842 if year >= 2000: 2843 self[date(year, SEP, 28)] = "Den české státnosti" 2844 if year >= 1951: 2845 self[date(year, OCT, 28)] = "Den vzniku samostatného " \ 2846 "československého státu" 2847 if year >= 1990: 2848 self[date(year, NOV, 17)] = "Den boje za svobodu a demokracii" 2849 2850 if year >= 1990: 2851 self[date(year, DEC, 24)] = "Štědrý den" 2852 if year >= 1951: 2853 self[date(year, DEC, 25)] = "1. svátek vánoční" 2854 self[date(year, DEC, 26)] = "2. svátek vánoční" 2855 2856 2857class CZ(Czechia): 2858 pass 2859 2860 2861class Czech(Czechia): 2862 def __init__(self, **kwargs): 2863 warnings.warn("Czech is deprecated, use Czechia instead.", 2864 DeprecationWarning) 2865 super(Czech, self).__init__(**kwargs) 2866 2867 2868class Slovakia(HolidayBase): 2869 # https://sk.wikipedia.org/wiki/Sviatok 2870 # https://www.slov-lex.sk/pravne-predpisy/SK/ZZ/1993/241/20181011.html 2871 2872 def __init__(self, **kwargs): 2873 self.country = 'SK' 2874 HolidayBase.__init__(self, **kwargs) 2875 2876 def _populate(self, year): 2877 self[date(year, JAN, 1)] = "Deň vzniku Slovenskej republiky" 2878 self[date(year, JAN, 6)] = "Zjavenie Pána (Traja králi a" \ 2879 " vianočnýsviatok pravoslávnych" \ 2880 " kresťanov)" 2881 2882 e = easter(year) 2883 self[e - rd(days=2)] = "Veľký piatok" 2884 self[e + rd(days=1)] = "Veľkonočný pondelok" 2885 2886 self[date(year, MAY, 1)] = "Sviatok práce" 2887 2888 if year >= 1997: 2889 self[date(year, MAY, 8)] = "Deň víťazstva nad fašizmom" 2890 2891 self[date(year, JUL, 5)] = "Sviatok svätého Cyrila a svätého Metoda" 2892 2893 self[date(year, AUG, 29)] = "Výročie Slovenského národného" \ 2894 " povstania" 2895 2896 self[date(year, SEP, 1)] = "Deň Ústavy Slovenskej republiky" 2897 2898 self[date(year, SEP, 15)] = "Sedembolestná Panna Mária" 2899 if year == 2018: 2900 self[date(year, OCT, 30)] = "100. výročie prijatia" \ 2901 " Deklarácie slovenského národa" 2902 self[date(year, NOV, 1)] = "Sviatok Všetkých svätých" 2903 2904 if year >= 2001: 2905 self[date(year, NOV, 17)] = "Deň boja za slobodu a demokraciu" 2906 2907 self[date(year, DEC, 24)] = "Štedrý deň" 2908 2909 self[date(year, DEC, 25)] = "Prvý sviatok vianočný" 2910 2911 self[date(year, DEC, 26)] = "Druhý sviatok vianočný" 2912 2913 2914class SK(Slovakia): 2915 pass 2916 2917 2918class Slovak(Slovakia): 2919 def __init__(self, **kwargs): 2920 warnings.warn("Slovak is deprecated, use Slovakia instead.", 2921 DeprecationWarning) 2922 super(Slovak, self).__init__(**kwargs) 2923 2924 2925class Poland(HolidayBase): 2926 # https://pl.wikipedia.org/wiki/Dni_wolne_od_pracy_w_Polsce 2927 2928 def __init__(self, **kwargs): 2929 self.country = 'PL' 2930 HolidayBase.__init__(self, **kwargs) 2931 2932 def _populate(self, year): 2933 self[date(year, JAN, 1)] = 'Nowy Rok' 2934 if year >= 2011: 2935 self[date(year, JAN, 6)] = 'Święto Trzech Króli' 2936 2937 e = easter(year) 2938 self[e] = 'Niedziela Wielkanocna' 2939 self[e + rd(days=1)] = 'Poniedziałek Wielkanocny' 2940 2941 if year >= 1950: 2942 self[date(year, MAY, 1)] = 'Święto Państwowe' 2943 if year >= 1919: 2944 self[date(year, MAY, 3)] = 'Święto Narodowe Trzeciego Maja' 2945 2946 self[e + rd(days=49)] = 'Zielone Świątki' 2947 self[e + rd(days=60)] = 'Dzień Bożego Ciała' 2948 2949 self[date(year, AUG, 15)] = 'Wniebowzięcie Najświętszej Marii Panny' 2950 2951 self[date(year, NOV, 1)] = 'Uroczystość Wszystkich świętych' 2952 if (1937 <= year <= 1945) or year >= 1989: 2953 self[date(year, NOV, 11)] = 'Narodowe Święto Niepodległości' 2954 2955 self[date(year, DEC, 25)] = 'Boże Narodzenie (pierwszy dzień)' 2956 self[date(year, DEC, 26)] = 'Boże Narodzenie (drugi dzień)' 2957 2958 2959class Polish(Poland): 2960 def __init__(self, **kwargs): 2961 warnings.warn("Polish is deprecated, use Poland instead.", 2962 DeprecationWarning) 2963 super(Polish, self).__init__(**kwargs) 2964 2965 2966class PL(Poland): 2967 pass 2968 2969 2970class Portugal(HolidayBase): 2971 # https://en.wikipedia.org/wiki/Public_holidays_in_Portugal 2972 2973 def __init__(self, **kwargs): 2974 self.country = 'PT' 2975 HolidayBase.__init__(self, **kwargs) 2976 2977 def _populate(self, year): 2978 self[date(year, JAN, 1)] = "Ano Novo" 2979 2980 e = easter(year) 2981 2982 # carnival is no longer a holiday, but some companies let workers off. 2983 # @todo recollect the years in which it was a public holiday 2984 # self[e - rd(days=47)] = "Carnaval" 2985 self[e - rd(days=2)] = "Sexta-feira Santa" 2986 self[e] = "Páscoa" 2987 2988 # Revoked holidays in 2013–2015 2989 if year < 2013 or year > 2015: 2990 self[e + rd(days=60)] = "Corpo de Deus" 2991 self[date(year, OCT, 5)] = "Implantação da República" 2992 self[date(year, NOV, 1)] = "Dia de Todos os Santos" 2993 self[date(year, DEC, 1)] = "Restauração da Independência" 2994 2995 self[date(year, 4, 25)] = "Dia da Liberdade" 2996 self[date(year, 5, 1)] = "Dia do Trabalhador" 2997 self[date(year, 6, 10)] = "Dia de Portugal" 2998 self[date(year, 8, 15)] = "Assunção de Nossa Senhora" 2999 self[date(year, DEC, 8)] = "Imaculada Conceição" 3000 self[date(year, DEC, 25)] = "Christmas Day" 3001 3002 3003class PT(Portugal): 3004 pass 3005 3006 3007class PortugalExt(Portugal): 3008 """ 3009 Adds extended days that most people have as a bonus from their companies: 3010 - Carnival 3011 - the day before and after xmas 3012 - the day before the new year 3013 - Lisbon's city holiday 3014 """ 3015 3016 def _populate(self, year): 3017 super(PortugalExt, self)._populate(year) 3018 3019 e = easter(year) 3020 self[e - rd(days=47)] = "Carnaval" 3021 self[date(year, DEC, 24)] = "Vespera de Natal" 3022 self[date(year, DEC, 26)] = "26 de Dezembro" 3023 self[date(year, DEC, 31)] = "Vespera de Ano novo" 3024 self[date(year, 6, 13)] = "Dia de Santo António" 3025 3026 # TODO add bridging days 3027 # - get Holidays that occur on Tuesday and add Monday (-1 day) 3028 # - get Holidays that occur on Thursday and add Friday (+1 day) 3029 3030 3031class PTE(PortugalExt): 3032 pass 3033 3034 3035class Netherlands(HolidayBase): 3036 SUN = 6 3037 3038 def __init__(self, **kwargs): 3039 # http://www.iamsterdam.com/en/plan-your-trip/practical-info/public-holidays 3040 self.country = "NL" 3041 HolidayBase.__init__(self, **kwargs) 3042 3043 def _populate(self, year): 3044 # New years 3045 self[date(year, JAN, 1)] = "Nieuwjaarsdag" 3046 3047 easter_date = easter(year) 3048 3049 # Easter 3050 self[easter_date] = "Eerste paasdag" 3051 3052 # Second easter day 3053 self[easter_date + rd(days=1)] = "Tweede paasdag" 3054 3055 # Ascension day 3056 self[easter_date + rd(days=39)] = "Hemelvaart" 3057 3058 # Pentecost 3059 self[easter_date + rd(days=49)] = "Eerste Pinksterdag" 3060 3061 # Pentecost monday 3062 self[easter_date + rd(days=50)] = "Tweede Pinksterdag" 3063 3064 # First christmas 3065 self[date(year, DEC, 25)] = "Eerste Kerstdag" 3066 3067 # Second christmas 3068 self[date(year, DEC, 26)] = "Tweede Kerstdag" 3069 3070 # Liberation day 3071 if year >= 1945 and year % 5 == 0: 3072 self[date(year, MAY, 5)] = "Bevrijdingsdag" 3073 3074 # Kingsday 3075 if year >= 2014: 3076 kings_day = date(year, APR, 27) 3077 if kings_day.weekday() == self.SUN: 3078 kings_day = kings_day - rd(days=1) 3079 3080 self[kings_day] = "Koningsdag" 3081 3082 # Queen's day 3083 if 1891 <= year <= 2013: 3084 queens_day = date(year, APR, 30) 3085 if year <= 1948: 3086 queens_day = date(year, AUG, 31) 3087 3088 if queens_day.weekday() == self.SUN: 3089 if year < 1980: 3090 queens_day = queens_day + rd(days=1) 3091 else: 3092 queens_day = queens_day - rd(days=1) 3093 3094 self[queens_day] = "Koninginnedag" 3095 3096 3097class NL(Netherlands): 3098 pass 3099 3100 3101class Norway(HolidayBase): 3102 """ 3103 Norwegian holidays. 3104 Note that holidays falling on a sunday is "lost", 3105 it will not be moved to another day to make up for the collision. 3106 3107 In Norway, ALL sundays are considered a holiday (https://snl.no/helligdag). 3108 Initialize this class with include_sundays=False 3109 to not include sundays as a holiday. 3110 3111 Primary sources: 3112 https://lovdata.no/dokument/NL/lov/1947-04-26-1 3113 https://no.wikipedia.org/wiki/Helligdager_i_Norge 3114 https://www.timeanddate.no/merkedag/norge/ 3115 """ 3116 3117 def __init__(self, include_sundays=True, **kwargs): 3118 """ 3119 3120 :param include_sundays: Whether to consider sundays as a holiday 3121 (which they are in Norway) 3122 :param kwargs: 3123 """ 3124 self.country = "NO" 3125 self.include_sundays = include_sundays 3126 HolidayBase.__init__(self, **kwargs) 3127 3128 def _populate(self, year): 3129 # Add all the sundays of the year before adding the "real" holidays 3130 if self.include_sundays: 3131 first_day_of_year = date(year, JAN, 1) 3132 first_sunday_of_year = \ 3133 first_day_of_year + \ 3134 rd(days=SUN - first_day_of_year.weekday()) 3135 cur_date = first_sunday_of_year 3136 3137 while cur_date < date(year + 1, 1, 1): 3138 assert cur_date.weekday() == SUN 3139 3140 self[cur_date] = "Søndag" 3141 cur_date += rd(days=7) 3142 3143 # ========= Static holidays ========= 3144 self[date(year, JAN, 1)] = "Første nyttårsdag" 3145 3146 # Source: https://lovdata.no/dokument/NL/lov/1947-04-26-1 3147 if year >= 1947: 3148 self[date(year, MAY, 1)] = "Arbeidernes dag" 3149 self[date(year, MAY, 17)] = "Grunnlovsdag" 3150 3151 # According to https://no.wikipedia.org/wiki/F%C3%B8rste_juledag, 3152 # these dates are only valid from year > 1700 3153 # Wikipedia has no source for the statement, so leaving this be for now 3154 self[date(year, DEC, 25)] = "Første juledag" 3155 self[date(year, DEC, 26)] = "Andre juledag" 3156 3157 # ========= Moving holidays ========= 3158 # NOTE: These are probably subject to the same > 1700 3159 # restriction as the above dates. The only source I could find for how 3160 # long Easter has been celebrated in Norway was 3161 # https://www.hf.uio.no/ikos/tjenester/kunnskap/samlinger/norsk-folkeminnesamling/livs-og-arshoytider/paske.html 3162 # which says 3163 # "(...) has been celebrated for over 1000 years (...)" (in Norway) 3164 e = easter(year) 3165 maundy_thursday = e - rd(days=3) 3166 good_friday = e - rd(days=2) 3167 resurrection_sunday = e 3168 easter_monday = e + rd(days=1) 3169 ascension_thursday = e + rd(days=39) 3170 pentecost = e + rd(days=49) 3171 pentecost_day_two = e + rd(days=50) 3172 3173 assert maundy_thursday.weekday() == THU 3174 assert good_friday.weekday() == FRI 3175 assert resurrection_sunday.weekday() == SUN 3176 assert easter_monday.weekday() == MON 3177 assert ascension_thursday.weekday() == THU 3178 assert pentecost.weekday() == SUN 3179 assert pentecost_day_two.weekday() == MON 3180 3181 self[maundy_thursday] = "Skjærtorsdag" 3182 self[good_friday] = "Langfredag" 3183 self[resurrection_sunday] = "Første påskedag" 3184 self[easter_monday] = "Andre påskedag" 3185 self[ascension_thursday] = "Kristi himmelfartsdag" 3186 self[pentecost] = "Første pinsedag" 3187 self[pentecost_day_two] = "Andre pinsedag" 3188 3189 3190class NO(Norway): 3191 pass 3192 3193 3194class Italy(HolidayBase): 3195 PROVINCES = ['AN', 'AO', 'BA', 'BL', 'BO', 3196 'BZ', 'BS', 'CB', 'CT', 'Cesena', 3197 'CH', 'CS', 'KR', 'EN', 'FE', 'FI', 3198 'FC', 'Forli', 'FR', 'GE', 'GO', 'IS', 3199 'SP', 'LT', 'MN', 'MS', 'MI', 3200 'MO', 'MB', 'NA', 'PD', 'PA', 3201 'PR', 'PG', 'PE', 'PC', 'PI', 3202 'PD', 'PT', 'RA', 'RE', 3203 'RI', 'RN', 'RM', 'RO', 'SA', 3204 'SR', 'TE', 'TO', 'TS', 'Pesaro', 'PU', 3205 'Urbino', 'VE', 'VC', 'VI'] 3206 3207 def __init__(self, **kwargs): 3208 self.country = 'IT' 3209 self.prov = kwargs.pop('prov', kwargs.pop('state', '')) 3210 HolidayBase.__init__(self, **kwargs) 3211 3212 def _populate(self, year): 3213 self[date(year, JAN, 1)] = "Capodanno" 3214 self[date(year, JAN, 6)] = "Epifania del Signore" 3215 self[easter(year)] = "Pasqua di Resurrezione" 3216 self[easter(year) + rd(weekday=MO)] = "Lunedì dell'Angelo" 3217 if year >= 1946: 3218 self[date(year, APR, 25)] = "Festa della Liberazione" 3219 self[date(year, MAY, 1)] = "Festa dei Lavoratori" 3220 if year >= 1948: 3221 self[date(year, JUN, 2)] = "Festa della Repubblica" 3222 self[date(year, AUG, 15)] = "Assunzione della Vergine" 3223 self[date(year, NOV, 1)] = "Tutti i Santi" 3224 self[date(year, DEC, 8)] = "Immacolata Concezione" 3225 self[date(year, DEC, 25)] = "Natale" 3226 self[date(year, DEC, 26)] = "Santo Stefano" 3227 3228 # Provinces holidays 3229 if self.prov: 3230 if self.prov == 'AN': 3231 self[date(year, MAY, 4)] = "San Ciriaco" 3232 elif self.prov == 'AO': 3233 self[date(year, SEP, 7)] = "San Grato" 3234 elif self.prov in ('BA'): 3235 self[date(year, DEC, 6)] = "San Nicola" 3236 elif self.prov == 'BL': 3237 self[date(year, NOV, 11)] = "San Martino" 3238 elif self.prov in ('BO'): 3239 self[date(year, OCT, 4)] = "San Petronio" 3240 elif self.prov == 'BZ': 3241 self[date(year, AUG, 15)] = "Maria Santissima Assunta" 3242 elif self.prov == 'BS': 3243 self[date(year, FEB, 15)] = "Santi Faustino e Giovita" 3244 elif self.prov == 'CB': 3245 self[date(year, APR, 23)] = "San Giorgio" 3246 elif self.prov == 'CT': 3247 self[date(year, FEB, 5)] = "Sant'Agata" 3248 elif self.prov in ('FC', 'Cesena'): 3249 self[date(year, JUN, 24)] = "San Giovanni Battista" 3250 if self.prov in ('FC', 'Forlì'): 3251 self[date(year, FEB, 4)] = "Madonna del Fuoco" 3252 elif self.prov == 'CH': 3253 self[date(year, MAY, 11)] = "San Giustino di Chieti" 3254 elif self.prov == 'CS': 3255 self[date(year, FEB, 12)] = "Madonna del Pilerio" 3256 elif self.prov == 'KR': 3257 self[date(year, OCT, 9)] = "San Dionigi" 3258 elif self.prov == 'EN': 3259 self[date(year, JUL, 2)] = "Madonna della Visitazione" 3260 elif self.prov == 'FE': 3261 self[date(year, APR, 23)] = "San Giorgio" 3262 elif self.prov == 'FI': 3263 self[date(year, JUN, 24)] = "San Giovanni Battista" 3264 elif self.prov == 'FR': 3265 self[date(year, JUN, 20)] = "San Silverio" 3266 elif self.prov == 'GE': 3267 self[date(year, JUN, 24)] = "San Giovanni Battista" 3268 elif self.prov == 'GO': 3269 self[date(year, MAR, 16)] = "Santi Ilario e Taziano" 3270 elif self.prov == 'IS': 3271 self[date(year, MAY, 19)] = "San Pietro Celestino" 3272 elif self.prov == 'SP': 3273 self[date(year, MAR, 19)] = "San Giuseppe" 3274 elif self.prov == 'LT': 3275 self[date(year, APR, 25)] = "San Marco evangelista" 3276 elif self.prov == 'ME': 3277 self[date(year, JUN, 3)] = "Madonna della Lettera" 3278 elif self.prov == 'MI': 3279 self[date(year, DEC, 7)] = "Sant'Ambrogio" 3280 elif self.prov == 'MN': 3281 self[date(year, MAR, 18)] = "Sant'Anselmo da Baggio" 3282 elif self.prov == 'MS': 3283 self[date(year, OCT, 4)] = "San Francesco d'Assisi" 3284 elif self.prov == 'MO': 3285 self[date(year, JAN, 31)] = "San Geminiano" 3286 elif self.prov == 'MB': 3287 self[date(year, JUN, 24)] = "San Giovanni Battista" 3288 elif self.prov == 'NA': 3289 self[date(year, SEP, 19)] = "San Gennaro" 3290 elif self.prov == 'PD': 3291 self[date(year, JUN, 13)] = "Sant'Antonio di Padova" 3292 elif self.prov == 'PA': 3293 self[date(year, JUL, 15)] = "San Giovanni" 3294 elif self.prov == 'PR': 3295 self[date(year, JAN, 13)] = "Sant'Ilario di Poitiers" 3296 elif self.prov == 'PG': 3297 self[date(year, JAN, 29)] = "Sant'Ercolano e San Lorenzo" 3298 elif self.prov == 'PC': 3299 self[date(year, JUL, 4)] = "Sant'Antonino di Piacenza" 3300 elif self.prov == 'RM': 3301 self[date(year, JUN, 29)] = "Santi Pietro e Paolo" 3302 elif self.prov == 'TO': 3303 self[date(year, JUN, 24)] = "San Giovanni Battista" 3304 elif self.prov == 'TS': 3305 self[date(year, NOV, 3)] = "San Giusto" 3306 elif self.prov == 'VI': 3307 self[date(year, APR, 25)] = "San Marco" 3308 3309 # TODO: add missing provinces' holidays: 3310 # 'Pisa', 'Pordenone', 'Potenza', 'Ravenna', 3311 # 'Reggio Emilia', 'Rieti', 'Rimini', 'Rovigo', 3312 # 'Salerno', 'Siracusa', 'Teramo', 'Torino', 'Urbino', 3313 # 'Venezia' 3314 3315 3316class IT(Italy): 3317 pass 3318 3319 3320class Sweden(HolidayBase): 3321 """ 3322 Swedish holidays. 3323 Note that holidays falling on a sunday are "lost", 3324 it will not be moved to another day to make up for the collision. 3325 In Sweden, ALL sundays are considered a holiday 3326 (https://sv.wikipedia.org/wiki/Helgdagar_i_Sverige). 3327 Initialize this class with include_sundays=False 3328 to not include sundays as a holiday. 3329 Primary sources: 3330 https://sv.wikipedia.org/wiki/Helgdagar_i_Sverige and 3331 http://www.riksdagen.se/sv/dokument-lagar/dokument/svensk-forfattningssamling/lag-1989253-om-allmanna-helgdagar_sfs-1989-253 3332 """ 3333 3334 def __init__(self, include_sundays=True, **kwargs): 3335 """ 3336 :param include_sundays: Whether to consider sundays as a holiday 3337 (which they are in Sweden) 3338 :param kwargs: 3339 """ 3340 self.country = "SE" 3341 self.include_sundays = include_sundays 3342 HolidayBase.__init__(self, **kwargs) 3343 3344 def _populate(self, year): 3345 # Add all the sundays of the year before adding the "real" holidays 3346 if self.include_sundays: 3347 first_day_of_year = date(year, JAN, 1) 3348 first_sunday_of_year = \ 3349 first_day_of_year + \ 3350 rd(days=SUN - first_day_of_year.weekday()) 3351 cur_date = first_sunday_of_year 3352 3353 while cur_date < date(year + 1, 1, 1): 3354 assert cur_date.weekday() == SUN 3355 3356 self[cur_date] = "Söndag" 3357 cur_date += rd(days=7) 3358 3359 # ========= Static holidays ========= 3360 self[date(year, JAN, 1)] = "Nyårsdagen" 3361 3362 self[date(year, JAN, 6)] = "Trettondedag jul" 3363 3364 # Source: https://sv.wikipedia.org/wiki/F%C3%B6rsta_maj 3365 if year >= 1939: 3366 self[date(year, MAY, 1)] = "Första maj" 3367 3368 # Source: https://sv.wikipedia.org/wiki/Sveriges_nationaldag 3369 if year >= 2005: 3370 self[date(year, JUN, 6)] = "Sveriges nationaldag" 3371 3372 self[date(year, DEC, 24)] = "Julafton" 3373 self[date(year, DEC, 25)] = "Juldagen" 3374 self[date(year, DEC, 26)] = "Annandag jul" 3375 self[date(year, DEC, 31)] = "Nyårsafton" 3376 3377 # ========= Moving holidays ========= 3378 e = easter(year) 3379 maundy_thursday = e - rd(days=3) 3380 good_friday = e - rd(days=2) 3381 easter_saturday = e - rd(days=1) 3382 resurrection_sunday = e 3383 easter_monday = e + rd(days=1) 3384 ascension_thursday = e + rd(days=39) 3385 pentecost = e + rd(days=49) 3386 pentecost_day_two = e + rd(days=50) 3387 3388 assert maundy_thursday.weekday() == THU 3389 assert good_friday.weekday() == FRI 3390 assert easter_saturday.weekday() == SAT 3391 assert resurrection_sunday.weekday() == SUN 3392 assert easter_monday.weekday() == MON 3393 assert ascension_thursday.weekday() == THU 3394 assert pentecost.weekday() == SUN 3395 assert pentecost_day_two.weekday() == MON 3396 3397 self[good_friday] = "Långfredagen" 3398 self[resurrection_sunday] = "Påskdagen" 3399 self[easter_monday] = "Annandag påsk" 3400 self[ascension_thursday] = "Kristi himmelsfärdsdag" 3401 self[pentecost] = "Pingstdagen" 3402 if year <= 2004: 3403 self[pentecost_day_two] = "Annandag pingst" 3404 3405 # Midsummer evening. Friday between June 19th and June 25th 3406 self[date(year, JUN, 19) + rd(weekday=FR)] = "Midsommarafton" 3407 3408 # Midsummer day. Saturday between June 20th and June 26th 3409 if year >= 1953: 3410 self[date(year, JUN, 20) + rd(weekday=SA)] = "Midsommardagen" 3411 else: 3412 self[date(year, JUN, 24)] = "Midsommardagen" 3413 # All saints day. Friday between October 31th and November 6th 3414 self[date(year, OCT, 31) + rd(weekday=SA)] = "Alla helgons dag" 3415 3416 if year <= 1953: 3417 self[date(year, MAR, 25)] = "Jungfru Marie bebådelsedag" 3418 3419 3420class SE(Sweden): 3421 pass 3422 3423 3424class Japan(HolidayBase): 3425 # https://en.wikipedia.org/wiki/Public_holidays_in_Japan 3426 3427 def __init__(self, **kwargs): 3428 self.country = 'JP' 3429 HolidayBase.__init__(self, **kwargs) 3430 3431 def _populate(self, year): 3432 if year < 1949 or year > 2099: 3433 raise NotImplementedError 3434 3435 # New Year's Day 3436 self[date(year, JAN, 1)] = "元日" 3437 3438 # Coming of Age Day 3439 if year <= 1999: 3440 self[date(year, JAN, 15)] = "成人の日" 3441 else: 3442 self[date(year, JAN, 1) + rd(weekday=MO(+2))] = "成人の日" 3443 3444 # Foundation Day 3445 self[date(year, FEB, 11)] = "建国記念の日" 3446 3447 # Reiwa Emperor's Birthday 3448 if year >= 2020: 3449 self[date(year, FEB, 23)] = '天皇誕生日' 3450 3451 # Vernal Equinox Day 3452 self[self._vernal_equinox_day(year)] = "春分の日" 3453 3454 # Showa Emperor's Birthday, Greenery Day or Showa Day 3455 if year <= 1988: 3456 self[date(year, APR, 29)] = "天皇誕生日" 3457 elif year <= 2006: 3458 self[date(year, APR, 29)] = "みどりの日" 3459 else: 3460 self[date(year, APR, 29)] = "昭和の日" 3461 3462 # Constitution Memorial Day 3463 self[date(year, MAY, 3)] = "憲法記念日" 3464 3465 # Greenery Day 3466 if year >= 2007: 3467 self[date(year, MAY, 4)] = "みどりの日" 3468 3469 # Children's Day 3470 self[date(year, MAY, 5)] = "こどもの日" 3471 3472 # Marine Day 3473 if 1996 <= year <= 2002: 3474 self[date(year, JUL, 20)] = "海の日" 3475 elif year >= 2003: 3476 self[date(year, JUL, 1) + rd(weekday=MO(+3))] = "海の日" 3477 3478 # Mountain Day 3479 if year >= 2016: 3480 self[date(year, AUG, 11)] = "山の日" 3481 3482 # Respect for the Aged Day 3483 if 1966 <= year <= 2002: 3484 self[date(year, SEP, 15)] = "敬老の日" 3485 elif year >= 2003: 3486 self[date(year, SEP, 1) + rd(weekday=MO(+3))] = "敬老の日" 3487 3488 # Autumnal Equinox Day 3489 self[self._autumnal_equinox_day(year)] = "秋分の日" 3490 3491 # Health and Sports Day 3492 if 1966 <= year <= 1999: 3493 self[date(year, OCT, 10)] = "体育の日" 3494 elif year >= 2000: 3495 self[date(year, OCT, 1) + rd(weekday=MO(+2))] = "体育の日" 3496 3497 # Culture Day 3498 self[date(year, NOV, 3)] = "文化の日" 3499 3500 # Labour Thanksgiving Day 3501 self[date(year, NOV, 23)] = "勤労感謝の日" 3502 3503 # Heisei Emperor's Birthday 3504 if 1989 <= year <= 2018: 3505 self[date(year, DEC, 23)] = "天皇誕生日" 3506 3507 # Regarding the Emperor of Reiwa 3508 if year == 2019: 3509 # Enthronement Day 3510 self[date(year, MAY, 1)] = '天皇の即位の日' 3511 # Enthronement ceremony 3512 self[date(year, OCT, 22)] = '即位礼正殿の儀が行われる日' 3513 3514 # A weekday between national holidays becomes a holiday too (国民の休日) 3515 self._add_national_holidays(year) 3516 3517 # Substitute holidays 3518 self._add_substitute_holidays(year) 3519 3520 def _vernal_equinox_day(self, year): 3521 day = 20 3522 if year % 4 == 0: 3523 if year <= 1956: 3524 day = 21 3525 elif year >= 2092: 3526 day = 19 3527 elif year % 4 == 1: 3528 if year <= 1989: 3529 day = 21 3530 elif year % 4 == 2: 3531 if year <= 2022: 3532 day = 21 3533 elif year % 4 == 3: 3534 if year <= 2055: 3535 day = 21 3536 return date(year, MAR, day) 3537 3538 def _autumnal_equinox_day(self, year): 3539 day = 22 3540 if year % 4 == 0: 3541 if year <= 2008: 3542 day = 23 3543 elif year % 4 == 1: 3544 if year <= 2041: 3545 day = 23 3546 elif year % 4 == 2: 3547 if year <= 2074: 3548 day = 23 3549 elif year % 4 == 3: 3550 if year <= 1979: 3551 day = 24 3552 else: 3553 day = 23 3554 return date(year, SEP, day) 3555 3556 def _add_national_holidays(self, year): 3557 if year in (1993, 1999, 2004, 1988, 1994, 2005, 1989, 1995, 2000, 2006, 3558 1990, 2001, 1991, 1996, 2002): 3559 self[date(year, MAY, 4)] = "国民の休日" 3560 3561 if year in (2032, 2049, 2060, 2077, 2088, 2094): 3562 self[date(year, SEP, 21)] = "国民の休日" 3563 3564 if year in (2009, 2015, 2026, 2037, 2043, 2054, 2065, 2071, 2099): 3565 self[date(year, SEP, 22)] = "国民の休日" 3566 3567 if year == 2019: 3568 self[date(year, APR, 30)] = '国民の休日' 3569 self[date(year, MAY, 2)] = '国民の休日' 3570 3571 def _add_substitute_holidays(self, year): 3572 table = ( 3573 (1, 2, (1978, 1984, 1989, 1995, 2006, 2012, 2017, 2023, 2034, 2040, 3574 2045)), 3575 (1, 16, (1978, 1984, 1989, 1995)), 3576 (2, 12, (1979, 1990, 1996, 2001, 2007, 2018, 2024, 2029, 2035, 3577 2046)), 3578 (2, 24, (2020,)), 3579 (3, 21, (1988, 2005, 2016, 2033, 2044, 2050)), 3580 (3, 22, (1982, 1999, 2010, 2027)), 3581 (4, 30, (1973, 1979, 1984, 1990, 2001, 2007, 2012, 2018, 2029, 3582 2035, 2040, 2046)), 3583 (5, 4, (1981, 1987, 1992, 1998)), 3584 (5, 6, (1985, 1991, 1996, 2002, 2013, 2019, 2024, 2030, 2041, 2047, 3585 2008, 2014, 2025, 2031, 2036, 2042, 2009, 2015, 2020, 2026, 3586 2037, 2043, 2048)), 3587 (7, 21, (1997,)), 3588 (8, 12, (2019, 2024, 2030, 2041, 2047)), 3589 (9, 16, (1974, 1985, 1991, 1996, 2002)), 3590 (9, 23, (2024,)), 3591 (9, 24, (1973, 1984, 1990, 2001, 2007, 2018, 2029, 2035, 2046)), 3592 (10, 11, (1976, 1982, 1993, 1999)), 3593 (11, 4, (1974, 1985, 1991, 1996, 2002, 2013, 2019, 2024, 2030, 3594 2041, 2047)), 3595 (11, 24, (1975, 1980, 1986, 1997, 2003, 2008, 2014, 2025, 2031, 3596 2036, 2042)), 3597 (12, 24, (1990, 2001, 2007, 2012, 2018)), 3598 ) 3599 for holiday in table: 3600 month = holiday[0] 3601 day = holiday[1] 3602 years = holiday[2] 3603 if year in years: 3604 self[date(year, month, day)] = "振替休日" 3605 3606 3607class JP(Japan): 3608 pass 3609 3610 3611class France(HolidayBase): 3612 """Official French holidays. 3613 3614 Some provinces have specific holidays, only those are included in the 3615 PROVINCES, because these provinces have different administrative status, 3616 which makes it difficult to enumerate. 3617 3618 For religious holidays usually happening on Sundays (Easter, Pentecost), 3619 only the following Monday is considered a holiday. 3620 3621 Primary sources: 3622 https://fr.wikipedia.org/wiki/Fêtes_et_jours_fériés_en_France 3623 https://www.service-public.fr/particuliers/vosdroits/F2405 3624 """ 3625 3626 PROVINCES = ['Métropole', 'Alsace-Moselle', 'Guadeloupe', 'Guyane', 3627 'Martinique', 'Mayotte', 'Nouvelle-Calédonie', 'La Réunion', 3628 'Polynésie Française', 'Saint-Barthélémy', 'Saint-Martin', 3629 'Wallis-et-Futuna'] 3630 3631 def __init__(self, **kwargs): 3632 self.country = 'FR' 3633 self.prov = kwargs.pop('prov', 'Métropole') 3634 HolidayBase.__init__(self, **kwargs) 3635 3636 def _populate(self, year): 3637 # Civil holidays 3638 if year > 1810: 3639 self[date(year, JAN, 1)] = "Jour de l'an" 3640 3641 if year > 1919: 3642 name = 'Fête du Travail' 3643 if year <= 1948: 3644 name += ' et de la Concorde sociale' 3645 self[date(year, MAY, 1)] = name 3646 3647 if (1953 <= year <= 1959) or year > 1981: 3648 self[date(year, MAY, 8)] = 'Armistice 1945' 3649 3650 if year >= 1880: 3651 self[date(year, JUL, 14)] = 'Fête nationale' 3652 3653 if year >= 1918: 3654 self[date(year, NOV, 11)] = 'Armistice 1918' 3655 3656 # Religious holidays 3657 if self.prov in ['Alsace-Moselle', 'Guadeloupe', 'Guyane', 3658 'Martinique', 'Polynésie Française']: 3659 self[easter(year) - rd(days=2)] = 'Vendredi saint' 3660 3661 if self.prov == 'Alsace-Moselle': 3662 self[date(year, DEC, 26)] = 'Deuxième jour de Noël' 3663 3664 if year >= 1886: 3665 self[easter(year) + rd(days=1)] = 'Lundi de Pâques' 3666 self[easter(year) + rd(days=50)] = 'Lundi de Pentecôte' 3667 3668 if year >= 1802: 3669 self[easter(year) + rd(days=39)] = 'Ascension' 3670 self[date(year, AUG, 15)] = 'Assomption' 3671 self[date(year, NOV, 1)] = 'Toussaint' 3672 3673 name = 'Noël' 3674 if self.prov == 'Alsace-Moselle': 3675 name = 'Premier jour de ' + name 3676 self[date(year, DEC, 25)] = name 3677 3678 # Non-metropolitan holidays (starting dates missing) 3679 if self.prov == 'Mayotte': 3680 self[date(year, APR, 27)] = "Abolition de l'esclavage" 3681 3682 if self.prov == 'Wallis-et-Futuna': 3683 self[date(year, APR, 28)] = 'Saint Pierre Chanel' 3684 3685 if self.prov == 'Martinique': 3686 self[date(year, MAY, 22)] = "Abolition de l'esclavage" 3687 3688 if self.prov in ['Guadeloupe', 'Saint-Martin']: 3689 self[date(year, MAY, 27)] = "Abolition de l'esclavage" 3690 3691 if self.prov == 'Guyane': 3692 self[date(year, JUN, 10)] = "Abolition de l'esclavage" 3693 3694 if self.prov == 'Polynésie Française': 3695 self[date(year, JUN, 29)] = "Fête de l'autonomie" 3696 3697 if self.prov in ['Guadeloupe', 'Martinique']: 3698 self[date(year, JUL, 21)] = 'Fête Victor Schoelcher' 3699 3700 if self.prov == 'Wallis-et-Futuna': 3701 self[date(year, JUL, 29)] = 'Fête du Territoire' 3702 3703 if self.prov == 'Nouvelle-Calédonie': 3704 self[date(year, SEP, 24)] = 'Fête de la Citoyenneté' 3705 3706 if self.prov == 'Saint-Barthélémy': 3707 self[date(year, OCT, 9)] = "Abolition de l'esclavage" 3708 3709 if self.prov == 'La Réunion' and year >= 1981: 3710 self[date(year, DEC, 20)] = "Abolition de l'esclavage" 3711 3712 3713# FR already exists (Friday), we don't want to mess it up 3714class FRA(France): 3715 pass 3716 3717 3718class Belgium(HolidayBase): 3719 """ 3720 https://www.belgium.be/nl/over_belgie/land/belgie_in_een_notendop/feestdagen 3721 https://nl.wikipedia.org/wiki/Feestdagen_in_Belgi%C3%AB 3722 """ 3723 3724 def __init__(self, **kwargs): 3725 self.country = "BE" 3726 HolidayBase.__init__(self, **kwargs) 3727 3728 def _populate(self, year): 3729 # New years 3730 self[date(year, JAN, 1)] = "Nieuwjaarsdag" 3731 3732 easter_date = easter(year) 3733 3734 # Easter 3735 self[easter_date] = "Pasen" 3736 3737 # Second easter day 3738 self[easter_date + rd(days=1)] = "Paasmaandag" 3739 3740 # Ascension day 3741 self[easter_date + rd(days=39)] = "O.L.H. Hemelvaart" 3742 3743 # Pentecost 3744 self[easter_date + rd(days=49)] = "Pinksteren" 3745 3746 # Pentecost monday 3747 self[easter_date + rd(days=50)] = "Pinkstermaandag" 3748 3749 # International Workers' Day 3750 self[date(year, MAY, 1)] = "Dag van de Arbeid" 3751 3752 # Belgian National Day 3753 self[date(year, JUL, 21)] = "Nationale feestdag" 3754 3755 # Assumption of Mary 3756 self[date(year, AUG, 15)] = "O.L.V. Hemelvaart" 3757 3758 # All Saints' Day 3759 self[date(year, NOV, 1)] = "Allerheiligen" 3760 3761 # Armistice Day 3762 self[date(year, NOV, 11)] = "Wapenstilstand" 3763 3764 # First christmas 3765 self[date(year, DEC, 25)] = "Kerstmis" 3766 3767 3768class BE(Belgium): 3769 pass 3770 3771 3772class SouthAfrica(HolidayBase): 3773 def __init__(self, **kwargs): 3774 # http://www.gov.za/about-sa/public-holidays 3775 # https://en.wikipedia.org/wiki/Public_holidays_in_South_Africa 3776 self.country = "ZA" 3777 HolidayBase.__init__(self, **kwargs) 3778 3779 def _populate(self, year): 3780 # Observed since 1910, with a few name changes 3781 if year > 1909: 3782 self[date(year, 1, 1)] = "New Year's Day" 3783 3784 e = easter(year) 3785 good_friday = e - rd(days=2) 3786 easter_monday = e + rd(days=1) 3787 self[good_friday] = "Good Friday" 3788 if year > 1979: 3789 self[easter_monday] = "Family Day" 3790 else: 3791 self[easter_monday] = "Easter Monday" 3792 3793 if 1909 < year < 1952: 3794 dec_16_name = "Dingaan's Day" 3795 elif 1951 < year < 1980: 3796 dec_16_name = "Day of the Covenant" 3797 elif 1979 < year < 1995: 3798 dec_16_name = "Day of the Vow" 3799 else: 3800 dec_16_name = "Day of Reconciliation" 3801 self[date(year, DEC, 16)] = dec_16_name 3802 3803 self[date(year, DEC, 25)] = "Christmas Day" 3804 3805 if year > 1979: 3806 dec_26_name = "Day of Goodwill" 3807 else: 3808 dec_26_name = "Boxing Day" 3809 self[date(year, 12, 26)] = dec_26_name 3810 3811 # Observed since 1995/1/1 3812 if year > 1994: 3813 self[date(year, MAR, 21)] = "Human Rights Day" 3814 self[date(year, APR, 27)] = "Freedom Day" 3815 self[date(year, MAY, 1)] = "Workers' Day" 3816 self[date(year, JUN, 16)] = "Youth Day" 3817 self[date(year, AUG, 9)] = "National Women's Day" 3818 self[date(year, SEP, 24)] = "Heritage Day" 3819 3820 # Once-off public holidays 3821 national_election = "National and provincial government elections" 3822 y2k = "Y2K changeover" 3823 local_election = "Local government elections" 3824 presidential = "By presidential decree" 3825 if year == 1999: 3826 self[date(1999, JUN, 2)] = national_election 3827 self[date(1999, DEC, 31)] = y2k 3828 if year == 2000: 3829 self[date(2000, JAN, 2)] = y2k 3830 if year == 2004: 3831 self[date(2004, APR, 14)] = national_election 3832 if year == 2006: 3833 self[date(2006, MAR, 1)] = local_election 3834 if year == 2008: 3835 self[date(2008, MAY, 2)] = presidential 3836 if year == 2009: 3837 self[date(2009, APR, 22)] = national_election 3838 if year == 2011: 3839 self[date(2011, MAY, 18)] = local_election 3840 self[date(2011, DEC, 27)] = presidential 3841 if year == 2014: 3842 self[date(2014, MAY, 7)] = national_election 3843 if year == 2016: 3844 self[date(2016, AUG, 3)] = local_election 3845 if year == 2019: 3846 self[date(2019, MAY, 8)] = national_election 3847 3848 # As of 1995/1/1, whenever a public holiday falls on a Sunday, 3849 # it rolls over to the following Monday 3850 for k, v in list(self.items()): 3851 if self.observed and year > 1994 and k.weekday() == SUN: 3852 self[k + rd(days=1)] = v + " (Observed)" 3853 3854 # Historic public holidays no longer observed 3855 if 1951 < year < 1974: 3856 self[date(year, APR, 6)] = "Van Riebeeck's Day" 3857 elif 1979 < year < 1995: 3858 self[date(year, APR, 6)] = "Founder's Day" 3859 3860 if 1986 < year < 1990: 3861 historic_workers_day = datetime(year, MAY, 1) 3862 # observed on first Friday in May 3863 while historic_workers_day.weekday() != FRI: 3864 historic_workers_day += rd(days=1) 3865 3866 self[historic_workers_day] = "Workers' Day" 3867 3868 if 1909 < year < 1994: 3869 ascension_day = e + rd(days=40) 3870 self[ascension_day] = "Ascension Day" 3871 3872 if 1909 < year < 1952: 3873 self[date(year, MAY, 24)] = "Empire Day" 3874 3875 if 1909 < year < 1961: 3876 self[date(year, MAY, 31)] = "Union Day" 3877 elif 1960 < year < 1994: 3878 self[date(year, MAY, 31)] = "Republic Day" 3879 3880 if 1951 < year < 1961: 3881 queens_birthday = datetime(year, JUN, 7) 3882 # observed on second Monday in June 3883 while queens_birthday.weekday() != 0: 3884 queens_birthday += rd(days=1) 3885 3886 self[queens_birthday] = "Queen's Birthday" 3887 3888 if 1960 < year < 1974: 3889 self[date(year, JUL, 10)] = "Family Day" 3890 3891 if 1909 < year < 1952: 3892 kings_birthday = datetime(year, AUG, 1) 3893 # observed on first Monday in August 3894 while kings_birthday.weekday() != 0: 3895 kings_birthday += rd(days=1) 3896 3897 self[kings_birthday] = "King's Birthday" 3898 3899 if 1951 < year < 1980: 3900 settlers_day = datetime(year, SEP, 1) 3901 while settlers_day.weekday() != 0: 3902 settlers_day += rd(days=1) 3903 3904 self[settlers_day] = "Settlers' Day" 3905 3906 if 1951 < year < 1994: 3907 self[date(year, OCT, 10)] = "Kruger Day" 3908 3909 3910class ZA(SouthAfrica): 3911 pass 3912 3913 3914class Slovenia(HolidayBase): 3915 """ 3916 Contains all work-free public holidays in Slovenia. 3917 No holidays are returned before year 1991 when Slovenia became independent 3918 country. Before that Slovenia was part of Socialist federal republic of 3919 Yugoslavia. 3920 3921 List of holidays (including those that are not work-free: 3922 https://en.wikipedia.org/wiki/Public_holidays_in_Slovenia 3923 """ 3924 3925 def __init__(self, **kwargs): 3926 self.country = 'SI' 3927 HolidayBase.__init__(self, **kwargs) 3928 3929 def _populate(self, year): 3930 if year <= 1990: 3931 return 3932 3933 if year > 1991: 3934 self[date(year, JAN, 1)] = "novo leto" 3935 3936 # Between 2012 and 2017 2nd January was not public holiday, 3937 # or at least not work-free day 3938 if year < 2013 or year > 2016: 3939 self[date(year, JAN, 2)] = "novo leto" 3940 3941 # Prešeren's day, slovenian cultural holiday 3942 self[date(year, FEB, 8)] = "Prešernov dan" 3943 3944 # Easter monday is the only easter related work-free day 3945 easter_day = easter(year) 3946 self[easter_day + rd(days=1)] = "Velikonočni ponedeljek" 3947 3948 # Day of uprising against occupation 3949 self[date(year, APR, 27)] = "dan upora proti okupatorju" 3950 3951 # Labour day, two days of it! 3952 self[date(year, MAY, 1)] = "praznik dela" 3953 self[date(year, MAY, 2)] = "praznik dela" 3954 3955 # Statehood day 3956 self[date(year, JUN, 25)] = "dan državnosti" 3957 3958 # Assumption day 3959 self[date(year, AUG, 15)] = "Marijino vnebovzetje" 3960 3961 # Reformation day 3962 self[date(year, OCT, 31)] = "dan reformacije" 3963 3964 # Remembrance day 3965 self[date(year, NOV, 1)] = "dan spomina na mrtve" 3966 3967 # Christmas 3968 self[date(year, DEC, 25)] = "Božič" 3969 3970 # Day of independence and unity 3971 self[date(year, DEC, 26)] = "dan samostojnosti in enotnosti" 3972 3973 3974class SI(Slovenia): 3975 pass 3976 3977 3978class Finland(HolidayBase): 3979 # https://en.wikipedia.org/wiki/Public_holidays_in_Finland 3980 3981 def __init__(self, **kwargs): 3982 self.country = "FI" 3983 HolidayBase.__init__(self, **kwargs) 3984 3985 def _populate(self, year): 3986 e = easter(year) 3987 3988 self[date(year, JAN, 1)] = "Uudenvuodenpäivä" 3989 self[date(year, JAN, 6)] = "Loppiainen" 3990 self[e - rd(days=2)] = "Pitkäperjantai" 3991 self[e] = "Pääsiäispäivä" 3992 self[e + rd(days=1)] = "2. pääsiäispäivä" 3993 self[date(year, MAY, 1)] = "Vappu" 3994 self[e + rd(days=39)] = "Helatorstai" 3995 self[e + rd(days=49)] = "Helluntaipäivä" 3996 self[date(year, JUN, 20) + rd(weekday=SA)] = "Juhannuspäivä" 3997 self[date(year, OCT, 31) + rd(weekday=SA)] = "Pyhäinpäivä" 3998 self[date(year, DEC, 6)] = "Itsenäisyyspäivä" 3999 self[date(year, DEC, 25)] = "Joulupäivä" 4000 self[date(year, DEC, 26)] = "Tapaninpäivä" 4001 4002 # Juhannusaatto (Midsummer Eve) and Jouluaatto (Christmas Eve) are not 4003 # official holidays, but are de facto. 4004 self[date(year, JUN, 19) + rd(weekday=FR)] = "Juhannusaatto" 4005 self[date(year, DEC, 24)] = "Jouluaatto" 4006 4007 4008class FI(Finland): 4009 pass 4010 4011 4012class Switzerland(HolidayBase): 4013 PROVINCES = ['AG', 'AR', 'AI', 'BL', 'BS', 'BE', 'FR', 'GE', 'GL', 4014 'GR', 'JU', 'LU', 'NE', 'NW', 'OW', 'SG', 'SH', 'SZ', 4015 'SO', 'TG', 'TI', 'UR', 'VD', 'VS', 'ZG', 'ZH'] 4016 4017 def __init__(self, **kwargs): 4018 self.country = 'CH' 4019 HolidayBase.__init__(self, **kwargs) 4020 4021 def _populate(self, year): 4022 # public holidays 4023 self[date(year, JAN, 1)] = 'Neujahrestag' 4024 4025 if self.prov in ('AG', 'BE', 'FR', 'GE', 'GL', 'GR', 'JU', 'LU', 4026 'NE', 'OW', 'SH', 'SO', 'TG', 'VD', 'ZG', 'ZH'): 4027 self[date(year, JAN, 2)] = 'Berchtoldstag' 4028 4029 if self.prov in ('SZ', 'TI', 'UR'): 4030 self[date(year, JAN, 6)] = 'Heilige Drei Könige' 4031 4032 if self.prov == 'NE': 4033 self[date(year, MAR, 1)] = 'Jahrestag der Ausrufung der Republik' 4034 4035 if self.prov in ('NW', 'SZ', 'TI', 'UR', 'VS'): 4036 self[date(year, MAR, 19)] = 'Josefstag' 4037 4038 # Näfelser Fahrt (first Thursday in April but not in Holy Week) 4039 if self.prov == 'GL' and year >= 1835: 4040 if ((date(year, APR, 1) + rd(weekday=FR)) != 4041 (easter(year) - rd(days=2))): 4042 self[date(year, APR, 1) + rd(weekday=TH)] = 'Näfelser Fahrt' 4043 else: 4044 self[date(year, APR, 8) + rd(weekday=TH)] = 'Näfelser Fahrt' 4045 4046 # it's a Holiday on a Sunday 4047 self[easter(year)] = 'Ostern' 4048 4049 # VS don't have easter 4050 if self.prov != 'VS': 4051 self[easter(year) - rd(days=2)] = 'Karfreitag' 4052 self[easter(year) + rd(weekday=MO)] = 'Ostermontag' 4053 4054 if self.prov in ('BL', 'BS', 'JU', 'NE', 'SH', 'SO', 'TG', 'TI', 4055 'ZH'): 4056 self[date(year, MAY, 1)] = 'Tag der Arbeit' 4057 4058 self[easter(year) + rd(days=39)] = 'Auffahrt' 4059 4060 # it's a Holiday on a Sunday 4061 self[easter(year) + rd(days=49)] = 'Pfingsten' 4062 4063 self[easter(year) + rd(days=50)] = 'Pfingstmontag' 4064 4065 if self.prov in ('AI', 'JU', 'LU', 'NW', 'OW', 'SZ', 'TI', 'UR', 4066 'VS', 'ZG'): 4067 self[easter(year) + rd(days=60)] = 'Fronleichnam' 4068 4069 if self.prov == 'JU': 4070 self[date(year, JUN, 23)] = 'Fest der Unabhängigkeit' 4071 4072 if self.prov == 'TI': 4073 self[date(year, JUN, 29)] = 'Peter und Paul' 4074 4075 if year >= 1291: 4076 self[date(year, AUG, 1)] = 'Nationalfeiertag' 4077 4078 if self.prov in ('AI', 'JU', 'LU', 'NW', 'OW', 'SZ', 'TI', 'UR', 4079 'VS', 'ZG'): 4080 self[date(year, AUG, 15)] = 'Mariä Himmelfahrt' 4081 4082 if self.prov == 'VD': 4083 # Monday after the third Sunday of September 4084 dt = date(year, SEP, 1) + rd(weekday=SU(+3)) + rd(weekday=MO) 4085 self[dt] = 'Lundi du Jeûne' 4086 4087 if self.prov == 'OW': 4088 self[date(year, SEP, 25)] = 'Bruder Klaus' 4089 4090 if self.prov in ('AI', 'GL', 'JU', 'LU', 'NW', 'OW', 'SG', 'SZ', 4091 'TI', 'UR', 'VS', 'ZG'): 4092 self[date(year, NOV, 1)] = 'Allerheiligen' 4093 4094 if self.prov in ('AI', 'LU', 'NW', 'OW', 'SZ', 'TI', 'UR', 'VS', 4095 'ZG'): 4096 self[date(year, DEC, 8)] = 'Mariä Empfängnis' 4097 4098 if self.prov == 'GE': 4099 self[date(year, DEC, 12)] = 'Escalade de Genève' 4100 4101 self[date(year, DEC, 25)] = 'Weihnachten' 4102 4103 if self.prov in ('AG', 'AR', 'AI', 'BL', 'BS', 'BE', 'FR', 'GL', 4104 'GR', 'LU', 'NE', 'NW', 'OW', 'SG', 'SH', 'SZ', 4105 'SO', 'TG', 'TI', 'UR', 'ZG', 'ZH'): 4106 self[date(year, DEC, 26)] = 'Stephanstag' 4107 4108 if self.prov == 'GE': 4109 self[date(year, DEC, 31)] = 'Wiederherstellung der Republik' 4110 4111 4112class CH(Switzerland): 4113 pass 4114 4115 4116class Honduras(HolidayBase): 4117 # https://www.timeanddate.com/holidays/honduras/ 4118 4119 def __init__(self, **kwargs): 4120 self.country = "HND" 4121 HolidayBase.__init__(self, **kwargs) 4122 4123 def _populate(self, year): 4124 # New Year's Day 4125 if self.observed and date(year, JAN, 1): 4126 self[date(year, JAN, 1)] = "Año Nuevo [New Year's Day]" 4127 4128 # The Three Wise Men Day 4129 if self.observed and date(year, JAN, 6): 4130 name = "Día de los Reyes Magos [The Three Wise Men Day] (Observed)" 4131 self[date(year, JAN, 6)] = name 4132 4133 # The Three Wise Men Day 4134 if self.observed and date(year, FEB, 3): 4135 name = "Día de la virgen de Suyapa [Our Lady of Suyapa] (Observed)" 4136 self[date(year, FEB, 3)] = name 4137 4138 # The Father's Day 4139 if self.observed and date(year, MAR, 19): 4140 name = "Día del Padre [Father's Day] (Observed)" 4141 self[date(year, MAR, 19)] = name 4142 4143 # Maundy Thursday 4144 self[easter(year) + rd(weekday=TH(-1)) 4145 ] = "Jueves Santo [Maundy Thursday]" 4146 4147 # Good Friday 4148 self[easter(year) + rd(weekday=FR(-1)) 4149 ] = "Viernes Santo [Good Friday]" 4150 4151 # Holy Saturday 4152 self[easter(year) + rd(weekday=SA(-1)) 4153 ] = "Sábado de Gloria [Holy Saturday]" 4154 4155 # Easter Sunday 4156 self[easter(year) + rd(weekday=SU(-1)) 4157 ] = "Domingo de Resurrección [Easter Sunday]" 4158 4159 # America Day 4160 if self.observed and date(year, APR, 14): 4161 self[date(year, APR, 14)] = "Día de las Américas [America Day]" 4162 4163 # Labor Day 4164 if self.observed and date(year, MAY, 1): 4165 self[date(year, MAY, 1)] = "Día del Trabajo [Labour Day]" 4166 4167 # Mother's Day 4168 may_first = date(int(year), 5, 1) 4169 weekday_seq = may_first.weekday() 4170 mom_day = (14 - weekday_seq) 4171 if self.observed and date(year, MAY, mom_day): 4172 str_day = "Día de la madre [Mother's Day] (Observed)" 4173 self[date(year, MAY, mom_day)] = str_day 4174 4175 # Children's Day 4176 if self.observed and date(year, SEP, 10): 4177 name = "Día del niño [Children day] (Observed)" 4178 self[date(year, SEP, 10)] = name 4179 4180 # Independence Day 4181 if self.observed and date(year, SEP, 15): 4182 name = "Día de la Independencia [Independence Day]" 4183 self[date(year, SEP, 15)] = name 4184 4185 # Teacher's Day 4186 if self.observed and date(year, SEP, 17): 4187 name = "Día del Maestro [Teacher's day] (Observed)" 4188 self[date(year, SEP, 17)] = name 4189 4190 # October Holidays are joined on 3 days starting at October 3 to 6. 4191 # Some companies work medium day and take the rest on saturday. 4192 # This holiday is variant and some companies work normally. 4193 # If start day is weekend is ignored. 4194 # The main objective of this is to increase the tourism. 4195 4196 # https://www.hondurastips.hn/2017/09/20/de-donde-nace-el-feriado-morazanico/ 4197 4198 if year <= 2014: 4199 # Morazan's Day 4200 if self.observed and date(year, OCT, 3): 4201 self[date(year, OCT, 3)] = "Día de Morazán [Morazan's Day]" 4202 4203 # Columbus Day 4204 if self.observed and date(year, OCT, 12): 4205 self[date(year, OCT, 12)] = "Día de la Raza [Columbus Day]" 4206 4207 # Amy Day 4208 if self.observed and date(year, OCT, 21): 4209 str_day = "Día de las Fuerzas Armadas [Army Day]" 4210 self[date(year, OCT, 21)] = str_day 4211 else: 4212 # Morazan Weekend 4213 if self.observed and date(year, OCT, 3): 4214 name = "Semana Morazánica [Morazan Weekend]" 4215 self[date(year, OCT, 3)] = name 4216 4217 # Morazan Weekend 4218 if self.observed and date(year, OCT, 4): 4219 name = "Semana Morazánica [Morazan Weekend]" 4220 self[date(year, OCT, 4)] = name 4221 4222 # Morazan Weekend 4223 if self.observed and date(year, OCT, 5): 4224 name = "Semana Morazánica [Morazan Weekend]" 4225 self[date(year, OCT, 5)] = name 4226 4227 # Christmas 4228 self[date(year, DEC, 25)] = "Navidad [Christmas]" 4229 4230 4231class HND(Honduras): 4232 pass 4233 4234 4235class Hungary(HolidayBase): 4236 # https://en.wikipedia.org/wiki/Public_holidays_in_Hungary 4237 # observed days off work around national holidays in the last 10 years: 4238 # https://www.munkaugyiforum.hu/munkaugyi-segedanyagok/ 4239 # 2018-evi-munkaszuneti-napok-koruli-munkarend-9-2017-ngm-rendelet 4240 # codification dates: 4241 # - https://hvg.hu/gazdasag/ 4242 # 20170307_Megszavaztak_munkaszuneti_nap_lett_a_nagypentek 4243 # - https://www.tankonyvtar.hu/hu/tartalom/historia/ 4244 # 92-10/ch01.html#id496839 4245 4246 def __init__(self, **kwargs): 4247 self.country = "HU" 4248 HolidayBase.__init__(self, **kwargs) 4249 4250 def _populate(self, year): 4251 # New years 4252 self._add_with_observed_day_off(date(year, JAN, 1), "Újév", since=2014) 4253 4254 # National Day 4255 if 1945 <= year <= 1950 or 1989 <= year: 4256 self._add_with_observed_day_off( 4257 date(year, MAR, 15), "Nemzeti ünnep") 4258 4259 # Soviet era 4260 if 1950 <= year <= 1989: 4261 # Proclamation of Soviet socialist governing system 4262 self[date(year, MAR, 21)] = \ 4263 "A Tanácsköztársaság kikiáltásának ünnepe" 4264 # Liberation Day 4265 self[date(year, APR, 4)] = "A felszabadulás ünnepe" 4266 # Memorial day of The Great October Soviet Socialist Revolution 4267 if year not in (1956, 1989): 4268 self[date(year, NOV, 7)] = \ 4269 "A nagy októberi szocialista forradalom ünnepe" 4270 4271 easter_date = easter(year) 4272 4273 # Good Friday 4274 if 2017 <= year: 4275 self[easter_date + rd(weekday=FR(-1))] = "Nagypéntek" 4276 4277 # Easter 4278 self[easter_date] = "Húsvét" 4279 4280 # Second easter day 4281 if 1955 != year: 4282 self[easter_date + rd(days=1)] = "Húsvét Hétfő" 4283 4284 # Pentecost 4285 self[easter_date + rd(days=49)] = "Pünkösd" 4286 4287 # Pentecost monday 4288 if year <= 1952 or 1992 <= year: 4289 self[easter_date + rd(days=50)] = "Pünkösdhétfő" 4290 4291 # International Workers' Day 4292 if 1946 <= year: 4293 self._add_with_observed_day_off( 4294 date(year, MAY, 1), "A Munka ünnepe") 4295 if 1950 <= year <= 1953: 4296 self[date(year, MAY, 2)] = "A Munka ünnepe" 4297 4298 # State Foundation Day (1771-????, 1891-) 4299 if 1950 <= year < 1990: 4300 self[date(year, AUG, 20)] = "A kenyér ünnepe" 4301 else: 4302 self._add_with_observed_day_off( 4303 date(year, AUG, 20), "Az államalapítás ünnepe") 4304 4305 # National Day 4306 if 1991 <= year: 4307 self._add_with_observed_day_off( 4308 date(year, OCT, 23), "Nemzeti ünnep") 4309 4310 # All Saints' Day 4311 if 1999 <= year: 4312 self._add_with_observed_day_off( 4313 date(year, NOV, 1), "Mindenszentek") 4314 4315 # Christmas Eve is not endorsed officially 4316 # but nowadays it is usually a day off work 4317 if self.observed and 2010 <= year \ 4318 and date(year, DEC, 24).weekday() not in WEEKEND: 4319 self[date(year, DEC, 24)] = "Szenteste" 4320 4321 # First christmas 4322 self[date(year, DEC, 25)] = "Karácsony" 4323 4324 # Second christmas 4325 if 1955 != year: 4326 self._add_with_observed_day_off( 4327 date(year, DEC, 26), "Karácsony másnapja", since=2013, 4328 before=False, after=True) 4329 4330 # New Year's Eve 4331 if self.observed and 2014 <= year \ 4332 and date(year, DEC, 31).weekday() == MON: 4333 self[date(year, DEC, 31)] = "Szilveszter" 4334 4335 def _add_with_observed_day_off(self, day, desc, since=2010, 4336 before=True, after=True): 4337 # Swapped days off were in place earlier but 4338 # I haven't found official record yet. 4339 self[day] = desc 4340 # TODO: should it be a separate flag? 4341 if self.observed and since <= day.year: 4342 if day.weekday() == TUE and before: 4343 self[day - rd(days=1)] = desc + " előtti pihenőnap" 4344 elif day.weekday() == THU and after: 4345 self[day + rd(days=1)] = desc + " utáni pihenőnap" 4346 4347 4348class HU(Hungary): 4349 pass 4350 4351 4352class India(HolidayBase): 4353 # https://en.wikipedia.org/wiki/Public_holidays_in_India 4354 # https://www.calendarlabs.com/holidays/india/ 4355 # https://slusi.dacnet.nic.in/watershedatlas/list_of_state_abbreviation.htm 4356 4357 PROVINCES = ['AS', 'CG', 'SK', 'KA', 'GJ', 'BR', 'RJ', 'OD', 4358 'TN', 'AP', 'WB', 'KL', 'HR', 'MH', 'MP', 'UP', 'UK', 'TS'] 4359 4360 def __init__(self, **kwargs): 4361 self.country = "IND" 4362 HolidayBase.__init__(self, **kwargs) 4363 4364 def _populate(self, year): 4365 # Pongal/ Makar Sankranti 4366 self[date(year, JAN, 14)] = "Makar Sankranti / Pongal" 4367 4368 if year >= 1950: 4369 # Republic Day 4370 self[date(year, JAN, 26)] = "Republic Day" 4371 4372 if year >= 1947: 4373 # Independence Day 4374 self[date(year, AUG, 15)] = "Independence Day" 4375 4376 # Gandhi Jayanti 4377 self[date(year, OCT, 2)] = "Gandhi Jayanti" 4378 4379 # Labour Day 4380 self[date(year, MAY, 1)] = "Labour Day" 4381 4382 # Christmas 4383 self[date(year, DEC, 25)] = "Christmas" 4384 4385 # GJ: Gujarat 4386 if self.prov == "GJ": 4387 self[date(year, JAN, 14)] = "Uttarayan" 4388 self[date(year, MAY, 1)] = "Gujarat Day" 4389 self[date(year, OCT, 31)] = "Sardar Patel Jayanti" 4390 4391 if self.prov == 'BR': 4392 self[date(year, MAR, 22)] = "Bihar Day" 4393 4394 if self.prov == 'RJ': 4395 self[date(year, MAR, 30)] = "Rajasthan Day" 4396 self[date(year, JUN, 15)] = "Maharana Pratap Jayanti" 4397 4398 if self.prov == 'OD': 4399 self[date(year, APR, 1)] = "Odisha Day (Utkala Dibasa)" 4400 self[date(year, APR, 15)] = "Maha Vishuva Sankranti / Pana" \ 4401 " Sankranti" 4402 4403 if self.prov in ('OD', 'AP', 'BR', 'WB', 'KL', 4404 'HR', 'MH', 'UP', 'UK', 'TN'): 4405 self[date(year, APR, 14)] = "Dr. B. R. Ambedkar's Jayanti" 4406 4407 if self.prov == 'TN': 4408 self[date(year, APR, 14)] = "Puthandu (Tamil New Year)" 4409 self[date(year, APR, 15)] = "Puthandu (Tamil New Year)" 4410 4411 if self.prov == 'WB': 4412 self[date(year, APR, 14)] = "Pohela Boishakh" 4413 self[date(year, APR, 15)] = "Pohela Boishakh" 4414 self[date(year, MAY, 9)] = "Rabindra Jayanti" 4415 4416 if self.prov == 'AS': 4417 self[date(year, APR, 15)] = "Bihu (Assamese New Year)" 4418 4419 if self.prov == 'MH': 4420 self[date(year, MAY, 1)] = "Maharashtra Day" 4421 4422 if self.prov == 'SK': 4423 self[date(year, MAY, 16)] = "Annexation Day" 4424 4425 if self.prov == 'KA': 4426 self[date(year, NOV, 1)] = "Karnataka Rajyotsava" 4427 4428 if self.prov == 'AP': 4429 self[date(year, NOV, 1)] = "Andhra Pradesh Foundation Day" 4430 4431 if self.prov == 'HR': 4432 self[date(year, NOV, 1)] = "Haryana Foundation Day" 4433 4434 if self.prov == 'MP': 4435 self[date(year, NOV, 1)] = "Madhya Pradesh Foundation Day" 4436 4437 if self.prov == 'KL': 4438 self[date(year, NOV, 1)] = "Kerala Foundation Day" 4439 4440 if self.prov == 'CG': 4441 self[date(year, NOV, 1)] = "Chhattisgarh Foundation Day" 4442 4443 # TS is Telangana State which was bifurcated in 2014 from AP 4444 # (AndhraPradesh) 4445 if self.prov == 'TS': 4446 self[date(year, OCT, 6)] = "Bathukamma Festival" 4447 self[date(year, APR, 6)] = "Eid al-Fitr" 4448 4449 4450class IND(India): 4451 pass 4452 4453 4454class Croatia(HolidayBase): 4455 4456 # https://en.wikipedia.org/wiki/Public_holidays_in_Croatia 4457 4458 def __init__(self, **kwargs): 4459 self.country = "HR" 4460 HolidayBase.__init__(self, **kwargs) 4461 4462 def _populate(self, year): 4463 # New years 4464 self[date(year, JAN, 1)] = "Nova Godina" 4465 # Epiphany 4466 self[date(year, JAN, 6)] = "Sveta tri kralja" 4467 easter_date = easter(year) 4468 4469 # Easter 4470 self[easter_date] = "Uskrs" 4471 # Easter Monday 4472 self[easter_date + rd(days=1)] = "Uskrsni ponedjeljak" 4473 4474 # Corpus Christi 4475 self[easter_date + rd(days=60)] = "Tijelovo" 4476 4477 # International Workers' Day 4478 self[date(year, MAY, 1)] = "Međunarodni praznik rada" 4479 4480 # Anti-fascist struggle day 4481 self[date(year, JUN, 22)] = "Dan antifašističke borbe" 4482 4483 # Statehood day 4484 self[date(year, JUN, 25)] = "Dan državnosti" 4485 4486 # Victory and Homeland Thanksgiving Day 4487 self[date(year, AUG, 5)] = "Dan pobjede i domovinske zahvalnosti" 4488 4489 # Assumption of Mary 4490 self[date(year, AUG, 15)] = "Velika Gospa" 4491 4492 # Independence Day 4493 self[date(year, OCT, 8)] = "Dan neovisnosti" 4494 4495 # All Saints' Day 4496 self[date(year, NOV, 1)] = "Svi sveti" 4497 4498 # Christmas day 4499 self[date(year, DEC, 25)] = "Božić" 4500 4501 # St. Stephen's day 4502 self[date(year, DEC, 26)] = "Sveti Stjepan" 4503 4504 4505class HR(Croatia): 4506 pass 4507 4508 4509class Luxembourg(HolidayBase): 4510 4511 # https://en.wikipedia.org/wiki/Public_holidays_in_Luxembourg 4512 4513 def __init__(self, **kwargs): 4514 self.country = 'LU' 4515 HolidayBase.__init__(self, **kwargs) 4516 4517 def _populate(self, year): 4518 # Public holidays 4519 self[date(year, JAN, 1)] = "Neijoerschdag" 4520 self[easter(year) + rd(weekday=MO)] = "Ouschterméindeg" 4521 self[date(year, MAY, 1)] = "Dag vun der Aarbecht" 4522 if year >= 2019: 4523 # Europe Day: not in legislation yet, but introduced starting 2019 4524 self[date(year, MAY, 9)] = "Europadag" 4525 self[easter(year) + rd(days=39)] = "Christi Himmelfaart" 4526 self[easter(year) + rd(days=50)] = "Péngschtméindeg" 4527 self[date(year, JUN, 23)] = "Nationalfeierdag" 4528 self[date(year, AUG, 15)] = "Léiffrawëschdag" 4529 self[date(year, NOV, 1)] = "Allerhellgen" 4530 self[date(year, DEC, 25)] = "Chrëschtdag" 4531 self[date(year, DEC, 26)] = "Stiefesdag" 4532 4533 4534class LU(Luxembourg): 4535 pass 4536 4537 4538class Russia(HolidayBase): 4539 """ 4540 https://en.wikipedia.org/wiki/Public_holidays_in_Russia 4541 """ 4542 4543 def __init__(self, **kwargs): 4544 self.country = "RU" 4545 HolidayBase.__init__(self, **kwargs) 4546 4547 def _populate(self, year): 4548 # New Year's Day 4549 self[date(year, JAN, 1)] = "Новый год" 4550 # New Year's Day 4551 self[date(year, JAN, 2)] = "Новый год" 4552 # New Year's Day 4553 self[date(year, JAN, 3)] = "Новый год" 4554 # New Year's Day 4555 self[date(year, JAN, 4)] = "Новый год" 4556 # New Year's Day 4557 self[date(year, JAN, 5)] = "Новый год" 4558 # New Year's Day 4559 self[date(year, JAN, 6)] = "Новый год" 4560 # Christmas Day (Orthodox) 4561 self[date(year, JAN, 7)] = "Православное Рождество" 4562 # New Year's Day 4563 self[date(year, JAN, 8)] = "Новый год" 4564 # Man Day 4565 self[date(year, FEB, 23)] = "День защитника отечества" 4566 # Women's Day 4567 self[date(year, MAR, 8)] = "День женщин" 4568 # Labour Day 4569 self[date(year, MAY, 1)] = "Праздник Весны и Труда" 4570 # Victory Day 4571 self[date(year, MAY, 9)] = "День Победы" 4572 # Russia's Day 4573 self[date(year, JUN, 12)] = "День России" 4574 # Unity Day 4575 self[date(year, NOV, 4)] = "День народного единства" 4576 4577 4578class RU(Russia): 4579 pass 4580 4581 4582class Lithuania(HolidayBase): 4583 4584 # https://en.wikipedia.org/wiki/Public_holidays_in_Lithuania 4585 # https://www.kalendorius.today/ 4586 4587 def __init__(self, **kwargs): 4588 self.country = "LT" 4589 HolidayBase.__init__(self, **kwargs) 4590 4591 def _populate(self, year): 4592 # New Year's Day 4593 self[date(year, 1, 1)] = "Naujieji metai" 4594 4595 # Day of Restoration of the State of Lithuania (1918) 4596 if year >= 1918: 4597 self[date(year, 2, 16)] = "Lietuvos valstybės " \ 4598 "atkūrimo diena" 4599 4600 # Day of Restoration of Independence of Lithuania 4601 # (from the Soviet Union, 1990) 4602 if year >= 1990: 4603 self[date(year, 3, 11)] = "Lietuvos nepriklausomybės " \ 4604 "atkūrimo diena" 4605 4606 # Easter 4607 easter_date = easter(year) 4608 self[easter_date] = "Velykos" 4609 4610 # Easter 2nd day 4611 self[easter_date + rd(days=1)] = "Velykų antroji diena" 4612 4613 # International Workers' Day 4614 self[date(year, 5, 1)] = "Tarptautinė darbo diena" 4615 4616 # Mother's day. First Sunday in May 4617 self[date(year, 5, 1) + rd(weekday=SU)] = "Motinos diena" 4618 4619 # Fathers's day. First Sunday in June 4620 self[date(year, 6, 1) + rd(weekday=SU)] = "Tėvo diena" 4621 4622 # St. John's Day [Christian name], 4623 # Day of Dew [original pagan name] 4624 if year >= 2003: 4625 self[date(year, 6, 24)] = "Joninės, Rasos" 4626 4627 # Statehood Day 4628 if year >= 1991: 4629 self[date(year, 7, 6)] = "Valstybės (Lietuvos " \ 4630 "karaliaus Mindaugo " \ 4631 "karūnavimo) diena" 4632 4633 # Assumption Day 4634 self[date(year, 8, 15)] = "Žolinė (Švč. Mergelės " \ 4635 "Marijos ėmimo į dangų diena)" 4636 4637 # All Saints' Day 4638 self[date(year, 11, 1)] = "Visų šventųjų diena (Vėlinės)" 4639 4640 # Christmas Eve 4641 self[date(year, 12, 24)] = "Šv. Kūčios" 4642 4643 # Christmas 1st day 4644 self[date(year, 12, 25)] = "Šv. Kalėdų pirma diena" 4645 4646 # Christmas 2nd day 4647 self[date(year, 12, 26)] = "Šv. Kalėdų antra diena" 4648 4649 4650class LT(Lithuania): 4651 pass 4652 4653 4654class Estonia(HolidayBase): 4655 def __init__(self, **kwargs): 4656 self.country = "EE" 4657 HolidayBase.__init__(self, **kwargs) 4658 4659 def _populate(self, year): 4660 e = easter(year) 4661 4662 # New Year's Day 4663 self[date(year, JAN, 1)] = "uusaasta" 4664 4665 # Independence Day, anniversary of the Republic of Estonia 4666 self[date(year, FEB, 24)] = "iseseisvuspäev" 4667 4668 # Good Friday 4669 self[e - rd(days=2)] = "suur reede" 4670 4671 # Easter Sunday 4672 self[e] = "ülestõusmispühade 1. püha" 4673 4674 # Spring Day 4675 self[date(year, MAY, 1)] = "kevadpüha" 4676 4677 # Pentecost 4678 self[e + rd(days=49)] = "nelipühade 1. püha" 4679 4680 # Victory Day 4681 self[date(year, JUN, 23)] = "võidupüha" 4682 4683 # Midsummer Day 4684 self[date(year, JUN, 24)] = "jaanipäev" 4685 4686 # Day of Restoration of Independence 4687 self[date(year, AUG, 20)] = "taasiseseisvumispäev" 4688 4689 # Christmas Eve 4690 self[date(year, DEC, 24)] = "jõululaupäev" 4691 4692 # Christmas Day 4693 self[date(year, DEC, 25)] = "esimene jõulupüha" 4694 4695 # Boxing Day 4696 self[date(year, DEC, 26)] = "teine jõulupüha" 4697 4698 4699class EE(Estonia): 4700 pass 4701 4702 4703class Iceland(HolidayBase): 4704 # https://en.wikipedia.org/wiki/Public_holidays_in_Iceland 4705 # https://www.officeholidays.com/countries/iceland/index.php 4706 def __init__(self, **kwargs): 4707 self.country = "IS" 4708 HolidayBase.__init__(self, **kwargs) 4709 4710 def _populate(self, year): 4711 # Public holidays 4712 self[date(year, JAN, 1)] = "Nýársdagur" 4713 self[easter(year) - rd(days=3)] = "Skírdagur" 4714 self[easter(year) + rd(weekday=FR(-1))] = "Föstudagurinn langi" 4715 self[easter(year)] = "Páskadagur" 4716 self[easter(year) + rd(days=1)] = "Annar í páskum" 4717 self[date(year, APR, 19) + rd(weekday=TH(+1))] = \ 4718 "Sumardagurinn fyrsti" 4719 self[date(year, MAY, 1)] = "Verkalýðsdagurinn" 4720 self[easter(year) + rd(days=39)] = "Uppstigningardagur" 4721 self[easter(year) + rd(days=49)] = "Hvítasunnudagur" 4722 self[easter(year) + rd(days=50)] = "Annar í hvítasunnu" 4723 self[date(year, JUN, 17)] = "Þjóðhátíðardagurinn" 4724 # First Monday of August 4725 self[date(year, AUG, 1) + rd(weekday=MO(+1))] = \ 4726 "Frídagur verslunarmanna" 4727 self[date(year, DEC, 24)] = "Aðfangadagur" 4728 self[date(year, DEC, 25)] = "Jóladagur" 4729 self[date(year, DEC, 26)] = "Annar í jólum" 4730 self[date(year, DEC, 31)] = "Gamlársdagur" 4731 4732 4733class IS(Iceland): 4734 pass 4735 4736 4737class Kenya(HolidayBase): 4738 # https://en.wikipedia.org/wiki/Public_holidays_in_Kenya 4739 # http://kenyaembassyberlin.de/Public-Holidays-in-Kenya.48.0.html 4740 def __init__(self, **kwargs): 4741 self.country = "KE" 4742 HolidayBase.__init__(self, **kwargs) 4743 4744 def _populate(self, year): 4745 # Public holidays 4746 self[date(year, JAN, 1)] = "New Year's Day" 4747 self[date(year, MAY, 1)] = "Labour Day" 4748 self[date(year, JUN, 1)] = "Madaraka Day" 4749 self[date(year, OCT, 20)] = "Mashujaa Day" 4750 self[date(year, DEC, 12)] = "Jamhuri (Independence) Day" 4751 self[date(year, DEC, 25)] = "Christmas Day" 4752 self[date(year, DEC, 26)] = "Boxing Day" 4753 for k, v in list(self.items()): 4754 if self.observed and k.weekday() == SUN: 4755 self[k + rd(days=1)] = v + " (Observed)" 4756 4757 self[easter(year) - rd(weekday=FR(-1))] = "Good Friday" 4758 self[easter(year) + rd(weekday=MO(+1))] = "Easter Monday" 4759 4760 4761class KE(Kenya): 4762 pass 4763 4764 4765class HongKong(HolidayBase): 4766 4767 # https://www.gov.hk/en/about/abouthk/holiday/2020.htm 4768 # https://en.wikipedia.org/wiki/Public_holidays_in_Hong_Kong 4769 4770 def __init__(self, **kwargs): 4771 self.country = "HK" 4772 HolidayBase.__init__(self, **kwargs) 4773 4774 def _populate(self, year): 4775 4776 day_following = "The day following " 4777 4778 # The first day of January 4779 name = "The first day of January" 4780 first_date = date(year, JAN, 1) 4781 if self.observed: 4782 if first_date.weekday() == SUN: 4783 self[first_date + rd(days=+1)] = day_following + \ 4784 self.first_lower(name) 4785 first_date = first_date + rd(days=+1) 4786 else: 4787 self[first_date] = name 4788 else: 4789 self[first_date] = name 4790 4791 # Lunar New Year 4792 name = "Lunar New Year's Day" 4793 preceding_day_lunar = "The day preceding Lunar New Year's Day" 4794 second_day_lunar = "The second day of Lunar New Year" 4795 third_day_lunar = "The third day of Lunar New Year" 4796 fourth_day_lunar = "The fourth day of Lunar New Year" 4797 dt = self.get_solar_date(year, 1, 1) 4798 new_year_date = date(dt.year, dt.month, dt.day) 4799 if self.observed: 4800 self[new_year_date] = name 4801 if new_year_date.weekday() in [MON, TUE, WED, THU]: 4802 self[new_year_date] = name 4803 self[new_year_date + rd(days=+1)] = second_day_lunar 4804 self[new_year_date + rd(days=+2)] = third_day_lunar 4805 elif new_year_date.weekday() == FRI: 4806 self[new_year_date] = name 4807 self[new_year_date + rd(days=+1)] = second_day_lunar 4808 self[new_year_date + rd(days=+3)] = fourth_day_lunar 4809 elif new_year_date.weekday() == SAT: 4810 self[new_year_date] = name 4811 self[new_year_date + rd(days=+2)] = third_day_lunar 4812 self[new_year_date + rd(days=+3)] = fourth_day_lunar 4813 elif new_year_date.weekday() == SUN: 4814 if year in [2006, 2007, 2010]: 4815 self[new_year_date + rd(days=-1)] = preceding_day_lunar 4816 self[new_year_date + rd(days=+1)] = second_day_lunar 4817 self[new_year_date + rd(days=+2)] = third_day_lunar 4818 else: 4819 self[new_year_date + rd(days=+1)] = second_day_lunar 4820 self[new_year_date + rd(days=+2)] = third_day_lunar 4821 self[new_year_date + rd(days=+3)] = fourth_day_lunar 4822 else: 4823 self[new_year_date] = name 4824 self[new_year_date + rd(days=+1)] = second_day_lunar 4825 self[new_year_date + rd(days=+2)] = third_day_lunar 4826 4827 # Ching Ming Festival 4828 name = "Ching Ming Festival" 4829 if self.isLeapYear(year) or (self.isLeapYear(year-1) and year > 2008): 4830 ching_ming_date = date(year, APR, 4) 4831 else: 4832 ching_ming_date = date(year, APR, 5) 4833 if self.observed: 4834 if ching_ming_date.weekday() == SUN: 4835 self[ching_ming_date + rd(days=+1)] = day_following + name 4836 ching_ming_date = ching_ming_date + rd(days=+1) 4837 else: 4838 self[ching_ming_date] = name 4839 else: 4840 self[ching_ming_date] = name 4841 4842 # Easter Holiday 4843 good_friday = "Good Friday" 4844 easter_monday = "Easter Monday" 4845 if self.observed: 4846 self[easter(year) + rd(weekday=FR(-1))] = good_friday 4847 self[easter(year) + rd(weekday=SA(-1))] = day_following + \ 4848 good_friday 4849 if ching_ming_date == easter(year) + rd(weekday=MO): 4850 self[easter(year) + rd(weekday=MO) + rd(days=+1)] = \ 4851 day_following + easter_monday 4852 else: 4853 self[easter(year) + rd(weekday=MO)] = easter_monday 4854 else: 4855 self[easter(year) + rd(weekday=FR(-1))] = good_friday 4856 self[easter(year) + rd(weekday=SA(-1))] = day_following + \ 4857 good_friday 4858 self[easter(year) + rd(weekday=MO)] = easter_monday 4859 4860 # Birthday of the Buddha 4861 name = "Birthday of the Buddha" 4862 dt = self.get_solar_date(year, 4, 8) 4863 buddha_date = date(dt.year, dt.month, dt.day) 4864 if self.observed: 4865 if buddha_date.weekday() == SUN: 4866 self[buddha_date + rd(days=+1)] = day_following + name 4867 else: 4868 self[buddha_date] = name 4869 else: 4870 self[buddha_date] = name 4871 4872 # Labour Day 4873 name = "Labour Day" 4874 labour_date = date(year, MAY, 1) 4875 if self.observed: 4876 if labour_date.weekday() == SUN: 4877 self[labour_date + rd(days=+1)] = day_following + name 4878 else: 4879 self[labour_date] = name 4880 else: 4881 self[labour_date] = name 4882 4883 # Tuen Ng Festival 4884 name = "Tuen Ng Festival" 4885 dt = self.get_solar_date(year, 5, 5) 4886 tuen_ng_date = date(dt.year, dt.month, dt.day) 4887 if self.observed: 4888 if tuen_ng_date.weekday() == SUN: 4889 self[tuen_ng_date + rd(days=+1)] = day_following + name 4890 else: 4891 self[tuen_ng_date] = name 4892 else: 4893 self[tuen_ng_date] = name 4894 4895 # Hong Kong Special Administrative Region Establishment Day 4896 name = "Hong Kong Special Administrative Region Establishment Day" 4897 hksar_date = date(year, JUL, 1) 4898 if self.observed: 4899 if hksar_date.weekday() == SUN: 4900 self[hksar_date + rd(days=+1)] = day_following + name 4901 else: 4902 self[hksar_date] = name 4903 else: 4904 self[hksar_date] = name 4905 4906 # Special holiday on 2015 - The 70th anniversary day of the victory 4907 # of the Chinese people's war of resistance against Japanese aggression 4908 name = "The 70th anniversary day of the victory of the Chinese " + \ 4909 "people's war of resistance against Japanese aggression" 4910 if year == 2015: 4911 self[date(year, SEP, 3)] = name 4912 4913 # Chinese Mid-Autumn Festival 4914 name = "Chinese Mid-Autumn Festival" 4915 dt = self.get_solar_date(year, 8, 15) 4916 mid_autumn_date = date(dt.year, dt.month, dt.day) 4917 if self.observed: 4918 if mid_autumn_date.weekday() == SAT: 4919 self[mid_autumn_date] = name 4920 else: 4921 self[mid_autumn_date + rd(days=+1)] = day_following + \ 4922 "the " + name 4923 mid_autumn_date = mid_autumn_date + rd(days=+1) 4924 else: 4925 self[mid_autumn_date] = name 4926 4927 # National Day 4928 name = "National Day" 4929 national_date = date(year, OCT, 1) 4930 if self.observed: 4931 if (national_date.weekday() == SUN or 4932 national_date == mid_autumn_date): 4933 self[national_date + rd(days=+1)] = day_following + name 4934 else: 4935 self[national_date] = name 4936 else: 4937 self[national_date] = name 4938 4939 # Chung Yeung Festival 4940 name = "Chung Yeung Festival" 4941 dt = self.get_solar_date(year, 9, 9) 4942 chung_yeung_date = date(dt.year, dt.month, dt.day) 4943 if self.observed: 4944 if chung_yeung_date.weekday() == SUN: 4945 self[chung_yeung_date + rd(days=+1)] = day_following + name 4946 else: 4947 self[chung_yeung_date] = name 4948 else: 4949 self[chung_yeung_date] = name 4950 4951 # Christmas Day 4952 name = "Christmas Day" 4953 first_after_christmas = "The first weekday after " + name 4954 second_after_christmas = "The second weekday after " + name 4955 christmas_date = date(year, DEC, 25) 4956 if self.observed: 4957 if christmas_date.weekday() == SUN: 4958 self[christmas_date] = name 4959 self[christmas_date + rd(days=+1)] = first_after_christmas 4960 self[christmas_date + rd(days=+2)] = second_after_christmas 4961 elif christmas_date.weekday() == SAT: 4962 self[christmas_date] = name 4963 self[christmas_date + rd(days=+2)] = first_after_christmas 4964 else: 4965 self[christmas_date] = name 4966 self[christmas_date + rd(days=+1)] = first_after_christmas 4967 else: 4968 self[christmas_date] = name 4969 self[christmas_date + rd(days=+1)] = day_following + name 4970 4971 def isLeapYear(self, year): 4972 if year % 4 != 0: 4973 return False 4974 elif year % 100 != 0: 4975 return True 4976 elif year % 400 != 0: 4977 return False 4978 else: 4979 return True 4980 4981 def first_lower(self, s): 4982 return s[0].lower() + s[1:] 4983 4984 # Store the number of days per year from 1901 to 2099, and the number of 4985 # days from the 1st to the 13th to store the monthly (including the month 4986 # of the month), 1 means that the month is 30 days. 0 means the month is 4987 # 29 days. The 12th to 15th digits indicate the month of the next month. 4988 # If it is 0x0F, it means that there is no leap month. 4989 g_lunar_month_days = [ 4990 0xF0EA4, 0xF1D4A, 0x52C94, 0xF0C96, 0xF1536, 4991 0x42AAC, 0xF0AD4, 0xF16B2, 0x22EA4, 0xF0EA4, # 1901-1910 4992 0x6364A, 0xF164A, 0xF1496, 0x52956, 0xF055A, 4993 0xF0AD6, 0x216D2, 0xF1B52, 0x73B24, 0xF1D24, # 1911-1920 4994 0xF1A4A, 0x5349A, 0xF14AC, 0xF056C, 0x42B6A, 4995 0xF0DA8, 0xF1D52, 0x23D24, 0xF1D24, 0x61A4C, # 1921-1930 4996 0xF0A56, 0xF14AE, 0x5256C, 0xF16B4, 0xF0DA8, 4997 0x31D92, 0xF0E92, 0x72D26, 0xF1526, 0xF0A56, # 1931-1940 4998 0x614B6, 0xF155A, 0xF0AD4, 0x436AA, 0xF1748, 4999 0xF1692, 0x23526, 0xF152A, 0x72A5A, 0xF0A6C, # 1941-1950 5000 0xF155A, 0x52B54, 0xF0B64, 0xF1B4A, 0x33A94, 5001 0xF1A94, 0x8152A, 0xF152E, 0xF0AAC, 0x6156A, # 1951-1960 5002 0xF15AA, 0xF0DA4, 0x41D4A, 0xF1D4A, 0xF0C94, 5003 0x3192E, 0xF1536, 0x72AB4, 0xF0AD4, 0xF16D2, # 1961-1970 5004 0x52EA4, 0xF16A4, 0xF164A, 0x42C96, 0xF1496, 5005 0x82956, 0xF055A, 0xF0ADA, 0x616D2, 0xF1B52, # 1971-1980 5006 0xF1B24, 0x43A4A, 0xF1A4A, 0xA349A, 0xF14AC, 5007 0xF056C, 0x60B6A, 0xF0DAA, 0xF1D92, 0x53D24, # 1981-1990 5008 0xF1D24, 0xF1A4C, 0x314AC, 0xF14AE, 0x829AC, 5009 0xF06B4, 0xF0DAA, 0x52D92, 0xF0E92, 0xF0D26, # 1991-2000 5010 0x42A56, 0xF0A56, 0xF14B6, 0x22AB4, 0xF0AD4, 5011 0x736AA, 0xF1748, 0xF1692, 0x53526, 0xF152A, # 2001-2010 5012 0xF0A5A, 0x4155A, 0xF156A, 0x92B54, 0xF0BA4, 5013 0xF1B4A, 0x63A94, 0xF1A94, 0xF192A, 0x42A5C, # 2011-2020 5014 0xF0AAC, 0xF156A, 0x22B64, 0xF0DA4, 0x61D52, 5015 0xF0E4A, 0xF0C96, 0x5192E, 0xF1956, 0xF0AB4, # 2021-2030 5016 0x315AC, 0xF16D2, 0xB2EA4, 0xF16A4, 0xF164A, 5017 0x63496, 0xF1496, 0xF0956, 0x50AB6, 0xF0B5A, # 2031-2040 5018 0xF16D4, 0x236A4, 0xF1B24, 0x73A4A, 0xF1A4A, 5019 0xF14AA, 0x5295A, 0xF096C, 0xF0B6A, 0x31B54, # 2041-2050 5020 0xF1D92, 0x83D24, 0xF1D24, 0xF1A4C, 0x614AC, 5021 0xF14AE, 0xF09AC, 0x40DAA, 0xF0EAA, 0xF0E92, # 2051-2060 5022 0x31D26, 0xF0D26, 0x72A56, 0xF0A56, 0xF14B6, 5023 0x52AB4, 0xF0AD4, 0xF16CA, 0x42E94, 0xF1694, # 2061-2070 5024 0x8352A, 0xF152A, 0xF0A5A, 0x6155A, 0xF156A, 5025 0xF0B54, 0x4174A, 0xF1B4A, 0xF1A94, 0x3392A, # 2071-2080 5026 0xF192C, 0x7329C, 0xF0AAC, 0xF156A, 0x52B64, 5027 0xF0DA4, 0xF1D4A, 0x41C94, 0xF0C96, 0x8192E, # 2081-2090 5028 0xF0956, 0xF0AB6, 0x615AC, 0xF16D4, 0xF0EA4, 5029 0x42E4A, 0xF164A, 0xF1516, 0x22936, # 2090-2099 5030 ] 5031 # Define range of years 5032 START_YEAR, END_YEAR = 1901, 1900 + len(g_lunar_month_days) 5033 # 1901 The 1st day of the 1st month of the Gregorian calendar is 1901/2/19 5034 LUNAR_START_DATE, SOLAR_START_DATE = (1901, 1, 1), datetime(1901, 2, 19) 5035 # The Gregorian date for December 30, 2099 is 2100/2/8 5036 LUNAR_END_DATE, SOLAR_END_DATE = (2099, 12, 30), datetime(2100, 2, 18) 5037 5038 def get_leap_month(self, lunar_year): 5039 return (self.g_lunar_month_days[lunar_year-self.START_YEAR] >> 16) \ 5040 & 0x0F 5041 5042 def lunar_month_days(self, lunar_year, lunar_month): 5043 return 29 + ((self.g_lunar_month_days[lunar_year-self.START_YEAR] >> 5044 lunar_month) & 0x01) 5045 5046 def lunar_year_days(self, year): 5047 days = 0 5048 months_day = self.g_lunar_month_days[year - self.START_YEAR] 5049 for i in range(1, 13 if self.get_leap_month(year) == 0x0F else 14): 5050 day = 29 + ((months_day >> i) & 0x01) 5051 days += day 5052 return days 5053 5054 # Calculate the Gregorian date according to the lunar calendar 5055 def get_solar_date(self, year, month, day): 5056 span_days = 0 5057 for y in range(self.START_YEAR, year): 5058 span_days += self.lunar_year_days(y) 5059 leap_month = self.get_leap_month(year) 5060 for m in range(1, month + (month > leap_month)): 5061 span_days += self.lunar_month_days(year, m) 5062 span_days += day - 1 5063 return self.SOLAR_START_DATE + timedelta(span_days) 5064 5065 5066class HK(HongKong): 5067 pass 5068 5069 5070class Peru(HolidayBase): 5071 # https://www.gob.pe/feriados 5072 # https://es.wikipedia.org/wiki/Anexo:Días_feriados_en_el_Perú 5073 def __init__(self, **kwargs): 5074 self.country = "PE" 5075 HolidayBase.__init__(self, **kwargs) 5076 5077 def _populate(self, year): 5078 # New Year's Day 5079 self[date(year, JAN, 1)] = "Año Nuevo [New Year's Day]" 5080 5081 # Feast of Saints Peter and Paul 5082 name = "San Pedro y San Pablo [Feast of Saints Peter and Paul]" 5083 self[date(year, JUN, 29)] = name 5084 5085 # Independence Day 5086 name = "Día de la Independencia [Independence Day]" 5087 self[date(year, JUL, 28)] = name 5088 5089 name = "Día de las Fuerzas Armadas y la Policía del Perú" 5090 self[date(year, JUL, 29)] = name 5091 5092 # Santa Rosa de Lima 5093 name = "Día de Santa Rosa de Lima" 5094 self[date(year, AUG, 30)] = name 5095 5096 # Battle of Angamos 5097 name = "Combate Naval de Angamos [Battle of Angamos]" 5098 self[date(year, OCT, 8)] = name 5099 5100 # Holy Thursday 5101 self[easter(year) + rd(weekday=TH(-1)) 5102 ] = "Jueves Santo [Maundy Thursday]" 5103 5104 # Good Friday 5105 self[easter(year) + rd(weekday=FR(-1)) 5106 ] = "Viernes Santo [Good Friday]" 5107 5108 # Holy Saturday 5109 self[easter(year) + rd(weekday=SA(-1)) 5110 ] = "Sábado de Gloria [Holy Saturday]" 5111 5112 # Easter Sunday 5113 self[easter(year) + rd(weekday=SU(-1)) 5114 ] = "Domingo de Resurrección [Easter Sunday]" 5115 5116 # Labor Day 5117 self[date(year, MAY, 1)] = "Día del Trabajo [Labour Day]" 5118 5119 # All Saints Day 5120 name = "Día de Todos Los Santos [All Saints Day]" 5121 self[date(year, NOV, 1)] = name 5122 5123 # Inmaculada Concepción 5124 name = "Inmaculada Concepción [Immaculate Conception]" 5125 self[date(year, DEC, 8)] = name 5126 5127 # Christmas 5128 self[date(year, DEC, 25)] = "Navidad [Christmas]" 5129 5130 5131class PE(Peru): 5132 pass 5133 5134 5135class Nigeria(HolidayBase): 5136 # https://en.wikipedia.org/wiki/Public_holidays_in_Nigeria 5137 def __init__(self, **kwargs): 5138 self.country = "NG" 5139 HolidayBase.__init__(self, **kwargs) 5140 5141 def _populate(self, year): 5142 # New Year's Day 5143 self[date(year, JAN, 1)] = "New Year's day" 5144 5145 # Worker's day 5146 self[date(year, MAY, 1)] = "Worker's day" 5147 5148 # Children's day 5149 self[date(year, MAY, 27)] = "Children's day" 5150 5151 # Democracy day 5152 self[date(year, JUN, 12)] = "Democracy day" 5153 5154 # Independence Day 5155 self[date(year, OCT, 1)] = "Independence day" 5156 5157 # Christmas day 5158 self[date(year, DEC, 25)] = "Christmas day" 5159 5160 # Boxing day 5161 self[date(year, DEC, 26)] = "Boxing day" 5162 5163 5164class NG(Nigeria): 5165 pass 5166 5167 5168class DominicanRepublic(HolidayBase): 5169 # http://ojd.org.do/Normativas/LABORAL/Leyes/Ley%20No.%20%20139-97.pdf 5170 # https://es.wikipedia.org/wiki/Rep%C3%BAblica_Dominicana#D%C3%ADas_festivos_nacionales 5171 5172 def __init__(self, **kwargs): 5173 self.country = 'DO' 5174 HolidayBase.__init__(self, **kwargs) 5175 5176 @staticmethod 5177 def __change_day_by_law(holiday, latest_days=(3, 4)): 5178 # Law No. 139-97 - Holidays Dominican Republic - Jun 27, 1997 5179 if holiday >= date(1997, 6, 27): 5180 if holiday.weekday() in [1, 2]: 5181 holiday -= rd(weekday=MO(-1)) 5182 elif holiday.weekday() in latest_days: 5183 holiday += rd(weekday=MO(1)) 5184 return holiday 5185 5186 def _populate(self, year): 5187 # New Year's Day 5188 self[date(year, JAN, 1)] = "Año Nuevo [New Year's Day]" 5189 5190 # Epiphany 5191 epiphany_day = self.__change_day_by_law(date(year, JAN, 6)) 5192 self[epiphany_day] = "Día de los Santos Reyes [Epiphany]" 5193 5194 # Lady of Altagracia 5195 self[date(year, JAN, 21)] = "Día de la Altagracia [Lady of Altagracia]" 5196 5197 # Juan Pablo Duarte Day 5198 duarte_day = self.__change_day_by_law(date(year, JAN, 26)) 5199 self[duarte_day] = "Día de Duarte [Juan Pablo Duarte Day]" 5200 5201 # Independence Day 5202 self[date(year, FEB, 27)] = "Día de Independencia [Independence Day]" 5203 5204 # Good Friday 5205 self[easter(year) + rd(weekday=FR(-1))] = "Viernes Santo [Good Friday]" 5206 5207 # Labor Day 5208 labor_day = self.__change_day_by_law(date(year, MAY, 1), (3, 4, 6)) 5209 self[labor_day] = "Día del Trabajo [Labor Day]" 5210 5211 # Feast of Corpus Christi 5212 self[date(year, JUN, 11)] = "Corpus Christi [Feast of Corpus Christi]" 5213 5214 # Restoration Day 5215 # Judgment No. 14 of Feb 20, 2008 of the Supreme Court of Justice 5216 restoration_day = date(year, AUG, 16) if ((year - 2000) % 4 == 0) \ 5217 and year < 2008 else self.__change_day_by_law(date(year, AUG, 16)) 5218 self[restoration_day] = "Día de la Restauración [Restoration Day]" 5219 5220 # Our Lady of Mercedes Day 5221 self[date(year, SEP, 24)] = "Día de las Mercedes \ 5222 [Our Lady of Mercedes Day]" 5223 5224 # Constitution Day 5225 constitution_day = self.__change_day_by_law(date(year, NOV, 6)) 5226 self[constitution_day] = "Día de la Constitución [Constitution Day]" 5227 5228 # Christmas Day 5229 self[date(year, DEC, 25)] = "Día de Navidad [Christmas Day]" 5230 5231 5232class DO(DominicanRepublic): 5233 pass 5234 5235 5236class Nicaragua(HolidayBase): 5237 PROVINCES = ['MN'] 5238 5239 def __init__(self, **kwargs): 5240 self.country = 'NI' 5241 self.prov = kwargs.pop('prov', kwargs.pop('state', 'MN')) 5242 HolidayBase.__init__(self, **kwargs) 5243 5244 def _populate(self, year): 5245 # New Years 5246 self[date(year, JAN, 1)] = "Año Nuevo [New Year's Day]" 5247 # Maundy Thursday 5248 self[easter(year) + rd(weekday=TH(-1))] =\ 5249 "Jueves Santo [Maundy Thursday]" 5250 # Good Friday 5251 self[easter(year) + rd(weekday=FR(-1))] = "Viernes Santo [Good Friday]" 5252 # Labor Day 5253 self[date(year, MAY, 1)] = "Día del Trabajo [Labour Day]" 5254 # Revolution Day 5255 if 2020 >= year >= 1979: 5256 self[date(year, JUL, 19)] = "Día de la Revolución [Revolution Day]" 5257 # Battle of San Jacinto Day 5258 self[date(year, SEP, 14)] =\ 5259 "Batalla de San Jacinto [Battle of San Jacinto]" 5260 # Independence Day 5261 self[date(year, SEP, 15)] =\ 5262 "Día de la Independencia [Independence Day]" 5263 # Virgin's Day 5264 self[date(year, DEC, 8)] = "Concepción de María [Virgin's Day]" 5265 # Christmas 5266 self[date(year, DEC, 25)] = "Navidad [Christmas]" 5267 5268 # Provinces festive day 5269 if self.prov: 5270 if self.prov == 'MN': 5271 # Santo Domingo Day Down 5272 self[date(year, AUG, 1)] = "Bajada de Santo Domingo" 5273 # Santo Domingo Day Up 5274 self[date(year, AUG, 10)] = "Subida de Santo Domingo" 5275 5276 5277class NI(Nicaragua): 5278 pass 5279