hdays.py 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347
  1. # Copyright (c) 2017-present, Facebook, Inc.
  2. # All rights reserved.
  3. #
  4. # This source code is licensed under the BSD-style license found in the
  5. # LICENSE file in the root directory of this source tree. An additional grant
  6. # of patent rights can be found in the PATENTS file in the same directory.
  7. from __future__ import absolute_import
  8. from __future__ import division
  9. from __future__ import print_function
  10. from __future__ import unicode_literals
  11. from holidays import HolidayBase, MONDAY, WEEKEND, rd, easter
  12. from lunardate import LunarDate
  13. from calendar import Calendar
  14. from datetime import date, timedelta
  15. from convertdate.islamic import to_gregorian, from_gregorian
  16. import warnings
  17. # Official public holidays at a country level
  18. # ------------ Holidays in Brazil---------------------
  19. class Brazil(HolidayBase):
  20. """
  21. Implement public holidays in Brazil
  22. Reference:
  23. https://en.wikipedia.org/wiki/Public_holidays_in_Brazil
  24. """
  25. def __init__(self, **kwargs):
  26. self.country = "BR"
  27. HolidayBase.__init__(self, **kwargs)
  28. def _populate(self, year):
  29. # New Year's Day
  30. if not self.observed and date(year, 1, 1).weekday() in WEEKEND:
  31. pass
  32. else:
  33. self[date(year, 1, 1)] = "New Year's Day"
  34. # Tiradentes
  35. self[date(year, 4, 21)] = "Tiradentes"
  36. # Worker's Day
  37. self[date(year, 5, 1)] = "Worker's Day"
  38. # Independence Day
  39. self[date(year, 9, 7)] = "Independence Day"
  40. # Our Lady of the Apparition
  41. self[date(year, 10, 12)] = "Our Lady of the Apparition"
  42. # All Souls' Day
  43. self[date(year, 11, 2)] = "All Souls' Day"
  44. # Republic Proclamation Day
  45. self[date(year, 11, 5)] = "Republic Proclamation Day"
  46. # Christmas
  47. self[date(year, 12, 25)] = "Christmas"
  48. class BR(Brazil):
  49. pass
  50. # ------------ Holidays in Indonesia---------------------
  51. class Indonesia(HolidayBase):
  52. """
  53. Implement public holidays in Indonesia
  54. Reference:
  55. https://en.wikipedia.org/wiki/Public_holidays_in_Indonesia
  56. Please note: Indonesia is a multi-cultural community and we only implement
  57. the national wide public holidays.
  58. """
  59. def __init__(self, **kwargs):
  60. self.country = "ID"
  61. HolidayBase.__init__(self, **kwargs)
  62. def _populate(self, year):
  63. # New Year's Day
  64. if not self.observed and date(year, 1, 1).weekday() in WEEKEND:
  65. pass
  66. else:
  67. self[date(year, 1, 1)] = "New Year's Day"
  68. # Chinese New Year/ Spring Festival
  69. name = "Chinese New Year"
  70. for offset in range(-1, 2, 1):
  71. ds = LunarDate(year + offset, 1, 1).toSolarDate()
  72. if ds.year == year:
  73. self[ds] = name
  74. # Day of Silence / Nyepi
  75. # Note:
  76. # This holiday is determined by Balinese calendar, which is not currently
  77. # available. Only hard coded version of this holiday from 2009 to 2019
  78. # is available.
  79. warning_msg = "We only support Nyepi holiday from 2009 to 2019"
  80. warnings.warn(warning_msg, Warning)
  81. name = "Day of Silence/ Nyepi"
  82. if year == 2009:
  83. self[date(year, 3, 26)] = name
  84. elif year == 2010:
  85. self[date(year, 3, 16)] = name
  86. elif year == 2011:
  87. self[date(year, 3, 5)] = name
  88. elif year == 2012:
  89. self[date(year, 3, 23)] = name
  90. elif year == 2013:
  91. self[date(year, 3, 12)] = name
  92. elif year == 2014:
  93. self[date(year, 3, 31)] = name
  94. elif year == 2015:
  95. self[date(year, 3, 21)] = name
  96. elif year == 2016:
  97. self[date(year, 3, 9)] = name
  98. elif year == 2017:
  99. self[date(year, 3, 28)] = name
  100. elif year == 2018:
  101. self[date(year, 3, 17)] = name
  102. elif year == 2019:
  103. self[date(year, 3, 7)] = name
  104. else:
  105. pass
  106. # Ascension of the Prophet
  107. name = "Ascension of the Prophet"
  108. for offset in range(-1, 2, 1):
  109. islam_year = from_gregorian(year + offset, 3, 17)[0]
  110. y, m, d = to_gregorian(islam_year, 7, 27)
  111. if y == year:
  112. self[date(y, m, d)] = name
  113. # Labor Day
  114. name = "Labor Day"
  115. self[date(year, 5, 1)] = name
  116. # Ascension of Jesus Christ
  117. name = "Ascension of Jesus"
  118. for offset in range(-1, 2, 1):
  119. ds = easter(year + offset) + rd(days=+39)
  120. if ds.year == year:
  121. self[ds] = name
  122. # Buddha's Birthday
  123. name = "Buddha's Birthday"
  124. for offset in range(-1, 2, 1):
  125. ds = LunarDate(year + offset, 4, 15).toSolarDate()
  126. if ds.year == year:
  127. self[ds] = name
  128. # Pancasila Day, since 2017
  129. if year >= 2017:
  130. name = "Pancasila Day"
  131. self[date(year, 6, 1)] = name
  132. # Eid al-Fitr
  133. name = "Eid al-Fitr"
  134. for offset in range(-1, 2, 1):
  135. islam_year = from_gregorian(year + offset, 6, 15)[0]
  136. y1, m1, d1 = to_gregorian(islam_year, 10, 1)
  137. y2, m2, d2 = to_gregorian(islam_year, 10, 2)
  138. if y1 == year:
  139. self[date(y1, m2, d2)] = name
  140. if y2 == year:
  141. self[date(y2, m2, d2)] = name
  142. # Independence Day
  143. name = "Independence Day"
  144. self[date(year, 8, 17)] = name
  145. # Feast of the Sacrifice
  146. name = "Feast of the Sacrifice"
  147. for offset in range(-1, 2, 1):
  148. islam_year = from_gregorian(year + offset, 8, 22)[0]
  149. y, m, d = to_gregorian(islam_year, 12, 10)
  150. if y == year:
  151. self[date(y, m, d)] = name
  152. # Islamic New Year
  153. name = "Islamic New Year"
  154. for offset in range(-1, 2, 1):
  155. islam_year = from_gregorian(year + offset, 9, 11)[0]
  156. y, m, d = to_gregorian(islam_year + 1, 1, 1)
  157. if y == year:
  158. self[date(y, m, d)] = name
  159. # Birth of the Prophet
  160. name = "Birth of the Prophet"
  161. for offset in range(-1, 2, 1):
  162. islam_year = from_gregorian(year + offset, 11, 20)[0]
  163. y, m, d = to_gregorian(islam_year + 1, 3, 12)
  164. if y == year:
  165. self[date(y, m, d)] = name
  166. # Christmas
  167. self[date(year, 12, 25)] = "Christmas"
  168. class ID(Indonesia):
  169. pass
  170. # ------------ Holidays in India---------------------
  171. class India(HolidayBase):
  172. """
  173. Implement public holidays in India
  174. Reference:
  175. https://en.wikipedia.org/wiki/Public_holidays_in_India
  176. Please note:
  177. India is a culturally diverse and fervent society, celebrate various
  178. holidays and festivals. We only implement the holidays that **all states
  179. and territories** celebrate.
  180. """
  181. def __init__(self, **kwargs):
  182. self.country = "IN"
  183. HolidayBase.__init__(self, **kwargs)
  184. def _populate(self, year):
  185. # --------------------------------
  186. # Three national days
  187. # Republic Day
  188. # Independence Day
  189. # Gandhi Jayanti
  190. # --------------------------------
  191. # Republic Day
  192. name = "Republic Day"
  193. self[date(year, 1, 26)] = name
  194. # Independence Day
  195. name = "Independence Day"
  196. self[date(year, 8, 15)] = name
  197. # Gandhi Jayanti
  198. name = "Gandhi Jayanti"
  199. self[date(year, 10, 2)] = name
  200. # --------------------------------
  201. # Hindo holidays
  202. # Diwali
  203. # Holi
  204. # --------------------------------
  205. # Diwali, Holi
  206. # http://www.theholidayspot.com/diwali/calendar.htm
  207. # https://www.timeanddate.com/holidays/india/diwali?starty=
  208. # https://www.infoplease.com/calendar-holidays/major-holidays/
  209. warning_msg = "We only support Diwali and Holi holidays from 2010 to 2025"
  210. warnings.warn(warning_msg, Warning)
  211. name1 = "Diwali"
  212. name2 = "Holi"
  213. if year == 2010:
  214. self[date(year, 12, 5)] = name1
  215. self[date(year, 2, 28)] = name2
  216. elif year == 2011:
  217. self[date(year, 10, 26)] = name1
  218. self[date(year, 3, 19)] = name2
  219. elif year == 2012:
  220. self[date(year, 11, 13)] = name1
  221. self[date(year, 3, 8)] = name2
  222. elif year == 2013:
  223. self[date(year, 11, 3)] = name1
  224. self[date(year, 3, 26)] = name2
  225. elif year == 2014:
  226. self[date(year, 10, 23)] = name1
  227. self[date(year, 3, 17)] = name2
  228. elif year == 2015:
  229. self[date(year, 11, 11)] = name1
  230. self[date(year, 3, 6)] = name2
  231. elif year == 2016:
  232. self[date(year, 10, 30)] = name1
  233. self[date(year, 3, 24)] = name2
  234. elif year == 2017:
  235. self[date(year, 10, 19)] = name1
  236. self[date(year, 3, 13)] = name2
  237. elif year == 2018:
  238. self[date(year, 11, 7)] = name1
  239. self[date(year, 3, 2)] = name2
  240. elif year == 2019:
  241. self[date(year, 10, 27)] = name1
  242. self[date(year, 3, 21)] = name2
  243. elif year == 2020:
  244. self[date(year, 11, 14)] = name1
  245. self[date(year, 3, 9)] = name2
  246. elif year == 2021:
  247. self[date(year, 11, 4)] = name1
  248. self[date(year, 3, 28)] = name2
  249. elif year == 2022:
  250. self[date(year, 10, 24)] = name1
  251. self[date(year, 3, 18)] = name2
  252. elif year == 2023:
  253. self[date(year, 10, 12)] = name1
  254. self[date(year, 3, 7)] = name2
  255. elif year == 2024:
  256. self[date(year, 11, 1)] = name1
  257. self[date(year, 3, 25)] = name2
  258. elif year == 2025:
  259. self[date(year, 10, 21)] = name1
  260. self[date(year, 3, 14)] = name2
  261. else:
  262. pass
  263. # --------------------------------
  264. # Islamic holidays
  265. # Day of Ashura
  266. # Mawlid
  267. # Eid ul-Fitr
  268. # Eid al-Adha
  269. # --------------------------------
  270. # Day of Ashura
  271. # 10th day of 1st Islamic month
  272. name = "Day of Ashura"
  273. for offset in range(-1, 2, 1):
  274. islam_year = from_gregorian(year + offset, 10, 1)[0]
  275. y, m, d = to_gregorian(islam_year, 1, 10)
  276. if y == year:
  277. self[date(y, m, d)] = name
  278. # Mawlid, Birth of the Prophet
  279. # 12th day of 3rd Islamic month
  280. name = "Mawlid"
  281. for offset in range(-1, 2, 1):
  282. islam_year = from_gregorian(year + offset, 11, 20)[0]
  283. y, m, d = to_gregorian(islam_year, 3, 12)
  284. if y == year:
  285. self[date(y, m, d)] = name
  286. # Eid ul-Fitr
  287. # 1st and 2nd day of 10th Islamic month
  288. name = "Eid al-Fitr"
  289. for offset in range(-1, 2, 1):
  290. islam_year = from_gregorian(year + offset, 6, 15)[0]
  291. y1, m1, d1 = to_gregorian(islam_year, 10, 1)
  292. y2, m2, d2 = to_gregorian(islam_year, 10, 2)
  293. if y1 == year:
  294. self[date(y1, m1, d1)] = name
  295. if y2 == year:
  296. self[date(y2, m2, d2)] = name
  297. # Eid al-Adha, i.e., Feast of the Sacrifice
  298. name = "Feast of the Sacrifice"
  299. for offset in range(-1, 2, 1):
  300. islam_year = from_gregorian(year + offset, 8, 22)[0]
  301. y, m, d = to_gregorian(islam_year, 12, 10)
  302. if y == year:
  303. self[date(y, m, d)] = name
  304. # --------------------------------
  305. # Christian holidays
  306. # New Year, Palm Sunday,
  307. # Maundy Thursday
  308. # Good Friday
  309. # Easter Sunday
  310. # Feast of Pentecost
  311. # Fest of St. Theresa of Calcutta
  312. # Feast of the Blessed Virgin
  313. # All Saints Day
  314. # All Souls Day
  315. # Christmas Day
  316. # Boxing Day
  317. # Feast of Holy Family
  318. # --------------------------------
  319. # New Year's Day
  320. self[date(year, 1, 1)] = "New Year's Day"
  321. # Palm Sunday
  322. name = "Palm Sunday"
  323. for offset in range(-1, 2, 1):
  324. ds = easter(year + offset) - rd(days=7)
  325. if ds.year == year:
  326. self[ds] = name
  327. # Maundy Thursday
  328. name = "Maundy Thursday"
  329. for offset in range(-1, 2, 1):
  330. ds = easter(year + offset) - rd(days=3)
  331. if ds.year == year:
  332. self[ds] = name
  333. # Good Friday
  334. name = "Good Friday"
  335. for offset in range(-1, 2, 1):
  336. ds = easter(year + offset) - rd(days=2)
  337. if ds.year == year:
  338. self[ds] = name
  339. # Easter Sunday
  340. name = "Easter Sunday"
  341. for offset in range(-1, 2, 1):
  342. ds = easter(year + offset)
  343. if ds.year == year:
  344. self[ds] = name
  345. # Feast of Pentecost
  346. name = "Feast of Pentecost"
  347. for offset in range(-1, 2, 1):
  348. ds = easter(year + offset) + rd(days=49)
  349. if ds.year == year:
  350. self[ds] = name
  351. # Fest of St. Theresa of Calcutta
  352. name = "Fest of St. Theresa of Calcutta"
  353. self[date(year, 9, 5)] = name
  354. # Feast of the Blessed Virgin
  355. name = "Feast of the Blessed Virgin"
  356. self[date(year, 9, 8)] = name
  357. # All Saints Day
  358. name = "All Saints Day"
  359. self[date(year, 11, 1)] = name
  360. # All Souls Day
  361. name = "All Souls Day"
  362. self[date(year, 11, 2)] = name
  363. # Christmas
  364. name = "Christmas Day"
  365. self[date(year, 12, 25)] = name
  366. # Boxing Day
  367. name = "Boxing Day"
  368. self[date(year, 12, 26)] = name
  369. # Feast of Holy Family
  370. name = "Feast of Holy Family"
  371. self[date(year, 12, 30)] = name
  372. class IN(India):
  373. pass
  374. # ------------ Holidays in Malaysia---------------------
  375. class Malaysia(HolidayBase):
  376. """
  377. Implement public holidays in Malaysia
  378. Reference:
  379. https://en.wikipedia.org/wiki/Public_holidays_in_Malaysia
  380. """
  381. def __init__(self, **kwargs):
  382. self.country = "MY"
  383. HolidayBase.__init__(self, **kwargs)
  384. def _populate(self, year):
  385. # New Year's Day
  386. name = "New Year's Day"
  387. self[date(year, 1, 1)] = name
  388. # Birthday of Prophet, Mawlid in India
  389. # 12th day of 3rd Islamic month
  390. name = "Birth of Prophet"
  391. for offset in range(-1, 2, 1):
  392. islam_year = from_gregorian(year + offset, 11, 20)[0]
  393. y, m, d = to_gregorian(islam_year, 3, 12)
  394. if y == year:
  395. self[date(y, m, d)] = name
  396. # Chinese New Year
  397. name = "Chinese New Year"
  398. for offset in range(-1, 2, 1):
  399. ds = LunarDate(year + offset, 1, 1).toSolarDate()
  400. if ds.year == year:
  401. self[ds] = name
  402. # Tamil New Year
  403. # Note: it's not necessarily 04/14
  404. # due to the local calendar
  405. # other possible dates are 04/13 and 04/15
  406. name = "Tamil New Year"
  407. self[date(year, 4, 14)] = name
  408. # Good Friday
  409. name = "Good Friday"
  410. for offset in range(-1, 2, 1):
  411. ds = easter(year + offset) - rd(days=2)
  412. if ds.year == year:
  413. self[ds] = name
  414. # Labor Day
  415. name = "Labor Day"
  416. self[date(year, 5, 1)] = name
  417. # Buddha's Birthday
  418. name = "Wesak Day"
  419. for offset in range(-1, 2, 1):
  420. ds = LunarDate(year + offset, 4, 15).toSolarDate()
  421. if ds.year == year:
  422. self[ds] = name
  423. # King's birthday
  424. # https://www.thestar.com.my/news/nation/2017/04/26/
  425. # Before 2017: first Saturday of June
  426. # 2017-2021: last Saturday of July
  427. name = "King's birthday"
  428. if year < 2017:
  429. c = Calendar(firstweekday=MONDAY)
  430. monthcal = c.monthdatescalendar(year, 6)
  431. l1 = len(monthcal)
  432. saturdays = []
  433. for i in range(l1):
  434. if monthcal[i][5].month == 6:
  435. saturdays.append(monthcal[i][5])
  436. self[saturdays[0]] = name
  437. elif (year >= 2017) and (year <= 2021):
  438. c = Calendar(firstweekday=MONDAY)
  439. monthcal = c.monthdatescalendar(year, 7)
  440. l1 = len(monthcal)
  441. saturdays = []
  442. for i in range(l1):
  443. if monthcal[i][5].month == 7:
  444. saturdays.append(monthcal[i][5])
  445. self[saturdays[-1]] = name
  446. # Eid al-Fitr
  447. name = "Eid al-Fitr"
  448. for offset in range(-1, 2, 1):
  449. islam_year = from_gregorian(year + offset, 6, 15)[0]
  450. y1, m1, d1 = to_gregorian(islam_year, 10, 1)
  451. y2, m2, d2 = to_gregorian(islam_year, 10, 2)
  452. if y1 == year:
  453. self[date(y1, m1, d1)] = name
  454. if y2 == year:
  455. self[date(y2, m2, d2)] = name
  456. # Malaysia Day
  457. name = "Malaysia Day"
  458. self[date(year, 9, 16)] = name
  459. # Feast of the Sacrifice
  460. name = "Feast of the Sacrifice"
  461. for offset in range(-1, 2, 1):
  462. islam_year = from_gregorian(year + offset, 8, 22)[0]
  463. y, m, d = to_gregorian(islam_year, 12, 10)
  464. if y == year:
  465. self[date(y, m, d)] = name
  466. # First Day of Muharram
  467. name = "First Day of Muharram"
  468. for offset in range(-1, 2, 1):
  469. islam_year = from_gregorian(year + offset, 9, 11)[0]
  470. y, m, d = to_gregorian(islam_year + 1, 1, 1)
  471. if y == year:
  472. self[date(y, m, d)] = name
  473. # Christmas
  474. name = "Christmas Day"
  475. self[date(year, 12, 25)] = name
  476. class MY(Malaysia):
  477. pass
  478. # ------------ Holidays in Vietnam---------------------
  479. class Vietnam(HolidayBase):
  480. """
  481. Implement public holidays in Vietnam
  482. Reference:
  483. https://en.wikipedia.org/wiki/Public_holidays_in_Vietnam
  484. """
  485. def __init__(self, **kwargs):
  486. self.country = "VN"
  487. HolidayBase.__init__(self, **kwargs)
  488. def _populate(self, year):
  489. # New Year's Day
  490. name = "New Year's Day"
  491. self[date(year, 1, 1)] = name
  492. # Vietnamese New Year
  493. name = "Vietnamese New Year"
  494. for offset in range(-1, 2, 1):
  495. try:
  496. ds = LunarDate(year - 1 + offset, 12, 30).toSolarDate()
  497. except ValueError:
  498. ds = LunarDate(year - 1 + offset, 12, 29).toSolarDate()
  499. if ds.year == year:
  500. self[ds] = name
  501. ds = LunarDate(year + offset, 1, 1).toSolarDate()
  502. if ds.year == year:
  503. self[ds] = name
  504. ds = LunarDate(year + offset, 1, 2).toSolarDate()
  505. if ds.year == year:
  506. self[ds] = name
  507. ds = LunarDate(year + offset, 1, 3).toSolarDate()
  508. if ds.year == year:
  509. self[ds] = name
  510. ds = LunarDate(year + offset, 1, 4).toSolarDate()
  511. if ds.year == year:
  512. self[ds] = name
  513. ds = LunarDate(year + offset, 1, 5).toSolarDate()
  514. if ds.year == year:
  515. self[ds] = name
  516. # Hung Kings Commemorations
  517. name = "Hung Kings Commemorations"
  518. for offset in range(-1, 2, 1):
  519. ds = LunarDate(year + offset, 3, 10).toSolarDate()
  520. if ds.year == year:
  521. self[ds] = name
  522. # Reunification Day
  523. name = "Reunification Day"
  524. self[date(year, 4, 30)] = name
  525. # Labor Day/International Workers' Day
  526. name = "Labor Day/International Workers' Day"
  527. self[date(year, 5, 1)] = name
  528. # National Day
  529. name = "National Day"
  530. self[date(year, 9, 2)] = name
  531. class VN(Vietnam):
  532. pass
  533. # ------------ Holidays in Thailand---------------------
  534. class Thailand(HolidayBase):
  535. """
  536. Implement public holidays in Thailand
  537. Reference:
  538. https://en.wikipedia.org/wiki/Public_holidays_in_Thailand
  539. """
  540. def __init__(self, **kwargs):
  541. self.country = "TH"
  542. HolidayBase.__init__(self, **kwargs)
  543. def _populate(self, year):
  544. # New Year's Day
  545. name = "New Year's Day"
  546. self[date(year, 1, 1)] = name
  547. # Magha Pujab
  548. # Note:
  549. # This holiday is determined by Buddhist calendar, which is not currently
  550. # available. Only hard coded version of this holiday from 2016 to 2019
  551. # is available.
  552. name = "Magha Pujab/Makha Bucha"
  553. if year == 2016:
  554. self[date(year, 2, 22)] = name
  555. elif year == 2017:
  556. self[date(year, 2, 11)] = name
  557. elif year == 2018:
  558. self[date(year, 3, 1)] = name
  559. elif year == 2019:
  560. self[date(year, 2, 19)] = name
  561. else:
  562. pass
  563. # Chakri Memorial Day
  564. name = "Chakri Memorial Day"
  565. april_6 = date(year, 4, 6).weekday()
  566. if april_6 == 5:
  567. self[date(year, 4, 6 + 2)] = name
  568. elif april_6 == 6:
  569. self[date(year, 4, 6 + 1)] = name
  570. else:
  571. self[date(year, 4, 6)] = name
  572. # Songkran Festival
  573. name = "Songkran Festival"
  574. self[date(year, 4, 14)] = name
  575. # Royal Ploughing Ceremony
  576. # arbitrary day in May
  577. # Buddha's Birthday
  578. name = "Buddha's Birthday"
  579. for offset in range(-1, 2, 1):
  580. ds = LunarDate(year + offset, 4, 15).toSolarDate()
  581. if ds.year == year:
  582. self[ds] = name
  583. # Coronation Day, removed in 2017
  584. name = "Coronation Day"
  585. if year < 2017:
  586. self[date(year, 5, 5)] = name
  587. # King Maha Vajiralongkorn's Birthday
  588. name = "King Maha Vajiralongkorn's Birthday"
  589. self[date(year, 7, 28)] = name
  590. # Asalha Puja
  591. # This is also a Buddha holiday, and we only implement
  592. # the hard coded version from 2006 to 2025
  593. # reference:
  594. # http://www.when-is.com/asalha_puja.asp
  595. warning_msg = "We only support Asalha Puja holiday from 2006 to 2025"
  596. warnings.warn(warning_msg, Warning)
  597. name = "Asalha Puja"
  598. if year == 2006:
  599. self[date(year, 7, 11)] = name
  600. elif year == 2007:
  601. self[date(year, 6, 30)] = name
  602. elif year == 2008:
  603. self[date(year, 7, 18)] = name
  604. elif year == 2009:
  605. self[date(year, 7, 7)] = name
  606. elif year == 2010:
  607. self[date(year, 7, 25)] = name
  608. elif year == 2011:
  609. self[date(year, 7, 15)] = name
  610. elif year == 2012:
  611. self[date(year, 8, 2)] = name
  612. elif year == 2013:
  613. self[date(year, 7, 30)] = name
  614. elif year == 2014:
  615. self[date(year, 7, 13)] = name
  616. elif year == 2015:
  617. self[date(year, 7, 30)] = name
  618. elif year == 2016:
  619. self[date(year, 7, 15)] = name
  620. elif year == 2017:
  621. self[date(year, 7, 9)] = name
  622. elif year == 2018:
  623. self[date(year, 7, 29)] = name
  624. elif year == 2019:
  625. self[date(year, 7, 16)] = name
  626. elif year == 2020:
  627. self[date(year, 7, 5)] = name
  628. elif year == 2021:
  629. self[date(year, 7, 24)] = name
  630. elif year == 2022:
  631. self[date(year, 7, 13)] = name
  632. elif year == 2023:
  633. self[date(year, 7, 3)] = name
  634. elif year == 2024:
  635. self[date(year, 7, 21)] = name
  636. elif year == 2025:
  637. self[date(year, 7, 10)] = name
  638. else:
  639. pass
  640. # Beginning of Vassa
  641. warning_msg = "We only support Vassa holiday from 2006 to 2020"
  642. warnings.warn(warning_msg, Warning)
  643. name = "Beginning of Vassa"
  644. if year == 2006:
  645. self[date(year, 7, 12)] = name
  646. elif year == 2007:
  647. self[date(year, 7, 31)] = name
  648. elif year == 2008:
  649. self[date(year, 7, 19)] = name
  650. elif year == 2009:
  651. self[date(year, 7, 8)] = name
  652. elif year == 2010:
  653. self[date(year, 7, 27)] = name
  654. elif year == 2011:
  655. self[date(year, 7, 16)] = name
  656. elif year == 2012:
  657. self[date(year, 8, 3)] = name
  658. elif year == 2013:
  659. self[date(year, 7, 23)] = name
  660. elif year == 2014:
  661. self[date(year, 7, 13)] = name
  662. elif year == 2015:
  663. self[date(year, 8, 1)] = name
  664. elif year == 2016:
  665. self[date(year, 7, 20)] = name
  666. elif year == 2017:
  667. self[date(year, 7, 9)] = name
  668. elif year == 2018:
  669. self[date(year, 7, 28)] = name
  670. elif year == 2019:
  671. self[date(year, 7, 17)] = name
  672. elif year == 2020:
  673. self[date(year, 7, 6)] = name
  674. else:
  675. pass
  676. # The Queen Sirikit's Birthday
  677. name = "The Queen Sirikit's Birthday"
  678. self[date(year, 8, 12)] = name
  679. # Anniversary for the Death of King Bhumibol Adulyadej
  680. name = "Anniversary for the Death of King Bhumibol Adulyadej"
  681. self[date(year, 10, 13)] = name
  682. # King Chulalongkorn Day
  683. name = "King Chulalongkorn Day"
  684. self[date(year, 10, 23)] = name
  685. # King Bhumibol Adulyadej's Birthday Anniversary
  686. name = "King Bhumibol Adulyadej's Birthday Anniversary"
  687. self[date(year, 12, 5)] = name
  688. # Constitution Day
  689. name = "Constitution Day"
  690. self[date(year, 12, 10)] = name
  691. # New Year's Eve
  692. name = "New Year's Eve"
  693. self[date(year, 12, 31)] = name
  694. class TH(Thailand):
  695. pass
  696. # ------------ Holidays in Philippines---------------------
  697. class Philippines(HolidayBase):
  698. """
  699. Implement public holidays in Philippines
  700. Reference:
  701. https://en.wikipedia.org/wiki/Public_holidays_in_Thailand
  702. """
  703. def __init__(self, **kwargs):
  704. self.country = "PH"
  705. HolidayBase.__init__(self, **kwargs)
  706. def _populate(self, year):
  707. # New Year's Day
  708. name = "New Year's Day"
  709. self[date(year, 1, 1)] = name
  710. # Maundy Thursday
  711. name = "Maundy Thursday"
  712. for offset in range(-1, 2, 1):
  713. ds = easter(year + offset) - rd(days=3)
  714. if ds.year == year:
  715. self[ds] = name
  716. # Good Friday
  717. name = "Good Friday"
  718. for offset in range(-1, 2, 1):
  719. ds = easter(year + offset) - rd(days=2)
  720. if ds.year == year:
  721. self[ds] = name
  722. # Day of Valor
  723. name = "Day of Valor"
  724. self[date(year, 4, 9)] = name
  725. # Labor Day
  726. name = "Labor Day"
  727. self[date(year, 5, 1)] = name
  728. # Independence Day
  729. name = "Independence Day"
  730. self[date(year, 6, 12)] = name
  731. # Eid al-Fitr
  732. name = "Eid al-Fitr"
  733. for offset in range(-1, 2, 1):
  734. islam_year = from_gregorian(year + offset, 6, 15)[0]
  735. y, m, d = to_gregorian(islam_year, 10, 1)
  736. ds = date(y, m, d) - timedelta(days=1)
  737. if ds.year == year:
  738. self[ds] = name
  739. # Eid al-Adha, i.e., Feast of the Sacrifice
  740. name = "Feast of the Sacrifice"
  741. for offset in range(-1, 2, 1):
  742. islam_year = from_gregorian(year + offset, 8, 22)[0]
  743. y, m, d = to_gregorian(islam_year, 12, 10)
  744. if y == year:
  745. self[date(y, m, d)] = name
  746. # National Heroes' Day
  747. name = "National Heroes' Day"
  748. self[date(year, 8, 27)] = name
  749. # Bonifacio Day
  750. name = "Bonifacio Day"
  751. self[date(year, 11, 30)] = name
  752. # Christmas Day
  753. name = "Christmas Day"
  754. self[date(year, 12, 25)] = name
  755. # Rizal Day
  756. name = "Rizal Day"
  757. self[date(year, 12, 30)] = name
  758. class PH(Philippines):
  759. pass
  760. # ------------ Holidays in Turkey---------------------
  761. class Turkey(HolidayBase):
  762. """
  763. Implement public holidays in Turkey
  764. Reference:
  765. https://en.wikipedia.org/wiki/Public_holidays_in_Thailand
  766. """
  767. def __init__(self, **kwargs):
  768. self.country = "TU"
  769. HolidayBase.__init__(self, **kwargs)
  770. def _populate(self, year):
  771. # New Year's Day
  772. name = "New Year's Day"
  773. self[date(year, 1, 1)] = name
  774. # National Sovereignty and Children's Day
  775. name = "National Sovereignty and Children's Day "
  776. self[date(year, 4, 23)] = name
  777. # Labor Day
  778. name = "Labor Day"
  779. self[date(year, 5, 1)] = name
  780. # Commemoration of Atatürk, Youth and Sports Day
  781. name = "Commemoration of Atatürk, Youth and Sports Day"
  782. self[date(year, 5, 19)] = name
  783. # Democracy and National Unity Day
  784. name = "Democracy and National Unity Day"
  785. self[date(year, 7, 15)] = name
  786. # Victory Day
  787. name = "Victory Day"
  788. self[date(year, 8, 30)] = name
  789. # Republic Day
  790. name = "Republic Day"
  791. self[date(year, 10, 29)] = name
  792. # Eid al-Fitr
  793. name = "Eid al-Fitr"
  794. for offset in range(-1, 2, 1):
  795. islam_year = from_gregorian(year + offset, 6, 15)[0]
  796. y, m, d = to_gregorian(islam_year, 10, 1)
  797. ds = date(y, m, d) - timedelta(days=1)
  798. if ds.year == year:
  799. self[ds] = name
  800. # Eid al-Adha, i.e., Feast of the Sacrifice
  801. name = "Feast of the Sacrifice"
  802. for offset in range(-1, 2, 1):
  803. islam_year = from_gregorian(year + offset, 8, 22)[0]
  804. y, m, d = to_gregorian(islam_year, 12, 10)
  805. if y == year:
  806. self[date(y, m, d)] = name
  807. class TU(Turkey):
  808. pass
  809. # ------------ Holidays in Pakistan---------------------
  810. class Pakistan(HolidayBase):
  811. """
  812. Implement public holidays in Pakistan
  813. Reference:
  814. https://en.wikipedia.org/wiki/Public_holidays_in_Pakistan
  815. """
  816. def __init__(self, **kwargs):
  817. self.country = "PK"
  818. HolidayBase.__init__(self, **kwargs)
  819. def _populate(self, year):
  820. # Kashmir Solidarity Day
  821. name = "Kashmir Solidarity Day"
  822. self[date(year, 2, 5)] = name
  823. # Pakistan Day
  824. name = "Pakistan Day"
  825. self[date(year, 3, 23)] = name
  826. # Labor Day
  827. name = "Labor Day"
  828. self[date(year, 5, 1)] = name
  829. # Independence Day
  830. name = "Independence Day"
  831. self[date(year, 8, 14)] = name
  832. # Iqbal Day
  833. name = "Iqbal Day"
  834. self[date(year, 11, 9)] = name
  835. # Christmas Day
  836. # Also birthday of PK founder
  837. name = "Christmas Day"
  838. self[date(year, 12, 25)] = name
  839. # Eid al-Adha, i.e., Feast of the Sacrifice
  840. name = "Feast of the Sacrifice"
  841. for offset in range(-1, 2, 1):
  842. islam_year = from_gregorian(year + offset, 8, 22)[0]
  843. y1, m1, d1 = to_gregorian(islam_year, 12, 10)
  844. y2, m2, d2 = to_gregorian(islam_year, 12, 11)
  845. y3, m3, d3 = to_gregorian(islam_year, 12, 12)
  846. if y1 == year:
  847. self[date(y1, m1, d1)] = name
  848. if y2 == year:
  849. self[date(y2, m2, d2)] = name
  850. if y3 == year:
  851. self[date(y3, m3, d3)] = name
  852. # Eid al-Fitr
  853. name = "Eid al-Fitr"
  854. for offset in range(-1, 2, 1):
  855. islam_year = from_gregorian(year + offset, 6, 15)[0]
  856. y1, m1, d1 = to_gregorian(islam_year, 10, 1)
  857. y2, m2, d2 = to_gregorian(islam_year, 10, 2)
  858. y3, m3, d3 = to_gregorian(islam_year, 10, 3)
  859. if y1 == year:
  860. self[date(y1, m1, d1)] = name
  861. if y2 == year:
  862. self[date(y2, m2, d2)] = name
  863. if y3 == year:
  864. self[date(y3, m3, d3)] = name
  865. # Mawlid, Birth of the Prophet
  866. # 12th day of 3rd Islamic month
  867. name = "Mawlid"
  868. for offset in range(-1, 2, 1):
  869. islam_year = from_gregorian(year + offset, 11, 20)[0]
  870. y, m, d = to_gregorian(islam_year, 3, 12)
  871. if y == year:
  872. self[date(y, m, d)] = name
  873. # Day of Ashura
  874. # 10th and 11th days of 1st Islamic month
  875. name = "Day of Ashura"
  876. for offset in range(-1, 2, 1):
  877. islam_year = from_gregorian(year + offset, 10, 1)[0]
  878. y1, m1, d1 = to_gregorian(islam_year, 1, 10)
  879. y2, m2, d2 = to_gregorian(islam_year, 1, 11)
  880. if y1 == year:
  881. self[date(y1, m1, d1)] = name
  882. if y2 == year:
  883. self[date(y2, m2, d2)] = name
  884. # Shab e Mairaj
  885. name = "Shab e Mairaj"
  886. for offset in range(-1, 2, 1):
  887. islam_year = from_gregorian(year + offset, 4, 13)[0]
  888. y, m, d = to_gregorian(islam_year, 7, 27)
  889. if y == year:
  890. self[date(y, m, d)] = name
  891. # Defence Day
  892. name = "Defence Day"
  893. self[date(year, 9, 6)] = name
  894. # Death Anniversary of Quaid-e-Azam
  895. name = "Death Anniversary of Quaid-e-Azam"
  896. self[date(year, 9, 11)] = name
  897. class PK(Pakistan):
  898. pass
  899. # ------------ Holidays in Bangladesh---------------------
  900. class Bangladesh(HolidayBase):
  901. """
  902. Implement public holidays in Bangladesh
  903. Reference:
  904. https://en.wikipedia.org/wiki/Public_holidays_in_Bangladesh
  905. """
  906. def __init__(self, **kwargs):
  907. self.country = "BD"
  908. HolidayBase.__init__(self, **kwargs)
  909. def _populate(self, year):
  910. # Language Martyrs' Day
  911. name = "Language Martyrs' Day"
  912. self[date(year, 2, 21)] = name
  913. # Mujib's birthday
  914. name = "Mujib's birthday"
  915. self[date(year, 3, 17)] = name
  916. # Independence Day
  917. name = "Independence Day"
  918. self[date(year, 3, 26)] = name
  919. # Bengali New Year's Day
  920. name = "Bengali New Year's Day"
  921. self[date(year, 4, 14)] = name
  922. # Labor Day, May Day (local name)
  923. name = "Labor Day"
  924. self[date(year, 5, 1)] = name
  925. # National Mourning Day
  926. name = "National Mourning Day"
  927. self[date(year, 8, 15)] = name
  928. # Victory Day
  929. name = "Victory Day"
  930. self[date(year, 12, 16)] = name
  931. class BD(Bangladesh):
  932. pass
  933. # ------------ Holidays in Egypt---------------------
  934. class Egypt(HolidayBase):
  935. """
  936. Implement public holidays in Egypt
  937. Reference:
  938. https://en.wikipedia.org/wiki/Public_holidays_in_Egypt
  939. """
  940. def __init__(self, **kwargs):
  941. self.country = "EG"
  942. HolidayBase.__init__(self, **kwargs)
  943. def _populate(self, year):
  944. # Fixed holidays
  945. # Christmas
  946. name = "Christmas"
  947. self[date(year, 1, 7)] = name
  948. # Revolution Day, after 2011
  949. name = "Revolution Day 2011"
  950. if year <= 2011:
  951. self[date(year, 1, 25)] = name
  952. # Sinai Liberation Day, after 1982
  953. name = "Sinai Liberation Day"
  954. if year <= 1982:
  955. self[date(year, 4, 25)] = name
  956. # Labor Day
  957. name = "Labor Day"
  958. self[date(year, 5, 1)] = name
  959. # Revolution Day
  960. name = "Sinai Liberation Day"
  961. self[date(year, 7, 23)] = name
  962. # Armed Forces Day
  963. name = "Armed Forces Day"
  964. self[date(year, 10, 6)] = name
  965. # Sham El Nessim
  966. # The Monday following Orthodox Easter
  967. name = "Sham El Nessim"
  968. for offset in range(-1, 2, 1):
  969. orthodox_easter = easter(year + offset, method=2)
  970. ds = orthodox_easter + timedelta(days=1)
  971. if ds.year == year:
  972. self[ds] = name
  973. # Islamic New Year
  974. name = "Islamic New Year"
  975. for offset in range(-1, 2, 1):
  976. islam_year = from_gregorian(year + offset, 9, 11)[0]
  977. y, m, d = to_gregorian(islam_year + 1, 1, 1)
  978. if y == year:
  979. self[date(y, m, d)] = name
  980. # Birthday of Prophet, Mawlid in India
  981. # 12th day of 3rd Islamic month
  982. name = "Birth of Prophet"
  983. for offset in range(-1, 2, 1):
  984. islam_year = from_gregorian(year + offset, 11, 20)[0]
  985. y, m, d = to_gregorian(islam_year, 3, 12)
  986. if y == year:
  987. self[date(y, m, d)] = name
  988. # Eid ul-Fitr
  989. # 1st and 2nd day of 10th Islamic month
  990. name = "Eid al-Fitr"
  991. for offset in range(-1, 2, 1):
  992. islam_year = from_gregorian(year + offset, 6, 15)[0]
  993. y1, m1, d1 = to_gregorian(islam_year, 10, 1)
  994. y2, m2, d2 = to_gregorian(islam_year, 10, 2)
  995. y3, m3, d3 = to_gregorian(islam_year, 10, 3)
  996. if y1 == year:
  997. self[date(y1, m1, d1)] = name
  998. if y2 == year:
  999. self[date(y2, m2, d2)] = name
  1000. if y3 == year:
  1001. self[date(y3, m3, d3)] = name
  1002. # Eid al-Adha, i.e., Feast of the Sacrifice
  1003. name = "Feast of the Sacrifice"
  1004. for offset in range(-1, 2, 1):
  1005. islam_year = from_gregorian(year + offset, 8, 22)[0]
  1006. y1, m1, d1 = to_gregorian(islam_year, 12, 10)
  1007. y2, m2, d2 = to_gregorian(islam_year, 12, 11)
  1008. y3, m3, d3 = to_gregorian(islam_year, 12, 12)
  1009. y4, m4, d4 = to_gregorian(islam_year, 12, 13)
  1010. if y1 == year:
  1011. self[date(y1, m1, d1)] = name
  1012. if y2 == year:
  1013. self[date(y2, m2, d2)] = name
  1014. if y3 == year:
  1015. self[date(y3, m3, d3)] = name
  1016. if y4 == year:
  1017. self[date(y4, m4, d4)] = name
  1018. class EG(Egypt):
  1019. pass
  1020. # ------------ Holidays in China---------------------
  1021. class China(HolidayBase):
  1022. """
  1023. Implement public holidays in China
  1024. Reference:
  1025. https://en.wikipedia.org/wiki/Public_holidays_in_China
  1026. """
  1027. def __init__(self, **kwargs):
  1028. self.country = "CN"
  1029. HolidayBase.__init__(self, **kwargs)
  1030. def _populate(self, year):
  1031. # New Year's Day
  1032. name = "New Year's Day"
  1033. self[date(year, 1, 1)] = name
  1034. # Chinese New Year/ Spring Festival
  1035. name = "Chinese New Year"
  1036. for offset in range(-1, 2, 1):
  1037. ds = LunarDate(year + offset, 1, 1).toSolarDate()
  1038. if ds.year == year:
  1039. self[ds] = name
  1040. # Tomb-Sweeping Day
  1041. name = "Tomb-Sweeping Day"
  1042. self[date(year, 4, 4)] = name
  1043. self[date(year, 4, 5)] = name
  1044. # Labor Day
  1045. name = "Labor Day"
  1046. self[date(year, 5, 1)] = name
  1047. # Dragon Boat Festival
  1048. name = "Dragon Boat Festival"
  1049. for offset in range(-1, 2, 1):
  1050. ds = LunarDate(year + offset, 5, 5).toSolarDate()
  1051. if ds.year == year:
  1052. self[ds] = name
  1053. # Mid-Autumn Festival
  1054. name = "Mid-Autumn Festival"
  1055. for offset in range(-1, 2, 1):
  1056. ds = LunarDate(year + offset, 8, 15).toSolarDate()
  1057. if ds.year == year:
  1058. self[ds] = name
  1059. # National Day
  1060. name = "National Day"
  1061. self[date(year, 10, 1)] = name
  1062. class CN(China):
  1063. pass
  1064. # ------------ Holidays in Russia---------------------
  1065. class Russia(HolidayBase):
  1066. """
  1067. Implement public holidays in Russia
  1068. Reference:
  1069. https://en.wikipedia.org/wiki/Public_holidays_in_Russia
  1070. Please note:
  1071. Orthodox Christmas Day is official day off at Russia
  1072. But the Dec. 25 Christmas is also celebrated.
  1073. """
  1074. def __init__(self, **kwargs):
  1075. self.country = "RU"
  1076. HolidayBase.__init__(self, **kwargs)
  1077. def _populate(self, year):
  1078. # New Year's Day
  1079. name = "New Year's Day"
  1080. self[date(year, 1, 1)] = name
  1081. # Orthodox Christmas day
  1082. name = "Orthodox Christmas Day"
  1083. self[date(year, 1, 7)] = name
  1084. # Dec. 25 Christmas Day
  1085. name = "Christmas Day"
  1086. self[date(year, 12, 25)] = name
  1087. # Defender of the Fatherland Day
  1088. name = "Defender of the Fatherland Day"
  1089. self[date(year, 2, 23)] = name
  1090. # International Women's Day
  1091. name = "International Women's Day"
  1092. self[date(year, 3, 8)] = name
  1093. # National Flag Day
  1094. name = "National Flag Day"
  1095. self[date(year, 8, 22)] = name
  1096. # Spring and Labour Day
  1097. name = "Spring and Labour Day"
  1098. self[date(year, 5, 1)] = name
  1099. # Victory Day
  1100. name = "Victory Day"
  1101. self[date(year, 5, 9)] = name
  1102. # Russia Day
  1103. name = "Russia Day"
  1104. self[date(year, 6, 12)] = name
  1105. # Unity Day
  1106. name = "Unity Day"
  1107. self[date(year, 11, 4)] = name
  1108. class RU(Russia):
  1109. pass