holidays 11.4.0 → 11.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +1 -0
  4. data/lib/generated_definitions/MANIFEST +1 -0
  5. data/lib/generated_definitions/REGIONS.rb +3 -3
  6. data/lib/generated_definitions/ar.rb +1 -18
  7. data/lib/generated_definitions/at.rb +1 -3
  8. data/lib/generated_definitions/au.rb +1 -86
  9. data/lib/generated_definitions/be_fr.rb +1 -3
  10. data/lib/generated_definitions/be_nl.rb +1 -3
  11. data/lib/generated_definitions/bg.rb +1 -3
  12. data/lib/generated_definitions/br.rb +1 -3
  13. data/lib/generated_definitions/by.rb +1 -3
  14. data/lib/generated_definitions/ca.rb +4 -14
  15. data/lib/generated_definitions/ch.rb +1 -48
  16. data/lib/generated_definitions/cl.rb +1 -33
  17. data/lib/generated_definitions/cn.rb +39 -0
  18. data/lib/generated_definitions/co.rb +1 -12
  19. data/lib/generated_definitions/cr.rb +1 -3
  20. data/lib/generated_definitions/cy.rb +1 -3
  21. data/lib/generated_definitions/cz.rb +1 -3
  22. data/lib/generated_definitions/de.rb +2 -14
  23. data/lib/generated_definitions/dk.rb +1 -3
  24. data/lib/generated_definitions/ecbtarget.rb +1 -3
  25. data/lib/generated_definitions/ee.rb +1 -3
  26. data/lib/generated_definitions/es.rb +1 -3
  27. data/lib/generated_definitions/europe.rb +4 -94
  28. data/lib/generated_definitions/federalreserve.rb +1 -3
  29. data/lib/generated_definitions/federalreservebanks.rb +1 -3
  30. data/lib/generated_definitions/fedex.rb +1 -7
  31. data/lib/generated_definitions/fi.rb +1 -25
  32. data/lib/generated_definitions/fr.rb +1 -3
  33. data/lib/generated_definitions/gb.rb +1 -3
  34. data/lib/generated_definitions/ge.rb +1 -3
  35. data/lib/generated_definitions/gr.rb +1 -3
  36. data/lib/generated_definitions/hk.rb +1 -3
  37. data/lib/generated_definitions/hr.rb +1 -3
  38. data/lib/generated_definitions/hu.rb +1 -3
  39. data/lib/generated_definitions/ie.rb +1 -12
  40. data/lib/generated_definitions/il.rb +1 -3
  41. data/lib/generated_definitions/in.rb +1 -3
  42. data/lib/generated_definitions/is.rb +1 -13
  43. data/lib/generated_definitions/it.rb +1 -3
  44. data/lib/generated_definitions/jp.rb +1 -95
  45. data/lib/generated_definitions/ke.rb +1 -3
  46. data/lib/generated_definitions/kr.rb +4 -6
  47. data/lib/generated_definitions/kz.rb +1 -3
  48. data/lib/generated_definitions/li.rb +1 -3
  49. data/lib/generated_definitions/lt.rb +1 -3
  50. data/lib/generated_definitions/lu.rb +1 -3
  51. data/lib/generated_definitions/lv.rb +1 -17
  52. data/lib/generated_definitions/ma.rb +1 -3
  53. data/lib/generated_definitions/mc.rb +1 -3
  54. data/lib/generated_definitions/mt_en.rb +1 -3
  55. data/lib/generated_definitions/mt_mt.rb +1 -3
  56. data/lib/generated_definitions/mx.rb +4 -4
  57. data/lib/generated_definitions/my.rb +1 -3
  58. data/lib/generated_definitions/nerc.rb +1 -3
  59. data/lib/generated_definitions/ng.rb +1 -3
  60. data/lib/generated_definitions/nl.rb +1 -3
  61. data/lib/generated_definitions/no.rb +1 -3
  62. data/lib/generated_definitions/northamerica.rb +5 -99
  63. data/lib/generated_definitions/nyse.rb +1 -3
  64. data/lib/generated_definitions/nz.rb +4 -70
  65. data/lib/generated_definitions/pe.rb +1 -3
  66. data/lib/generated_definitions/ph.rb +1 -9
  67. data/lib/generated_definitions/pl.rb +1 -3
  68. data/lib/generated_definitions/pt.rb +1 -3
  69. data/lib/generated_definitions/ro.rb +3 -5
  70. data/lib/generated_definitions/rs_cyrl.rb +1 -3
  71. data/lib/generated_definitions/rs_la.rb +1 -3
  72. data/lib/generated_definitions/ru.rb +1 -3
  73. data/lib/generated_definitions/scandinavia.rb +1 -47
  74. data/lib/generated_definitions/se.rb +1 -15
  75. data/lib/generated_definitions/sg.rb +1 -3
  76. data/lib/generated_definitions/si.rb +1 -3
  77. data/lib/generated_definitions/sk.rb +1 -3
  78. data/lib/generated_definitions/southamerica.rb +1 -57
  79. data/lib/generated_definitions/th.rb +1 -3
  80. data/lib/generated_definitions/tn.rb +1 -3
  81. data/lib/generated_definitions/tr.rb +1 -29
  82. data/lib/generated_definitions/tsx.rb +1 -13
  83. data/lib/generated_definitions/ua.rb +1 -3
  84. data/lib/generated_definitions/unitednations.rb +1 -3
  85. data/lib/generated_definitions/ups.rb +1 -7
  86. data/lib/generated_definitions/us.rb +5 -89
  87. data/lib/generated_definitions/ve.rb +1 -3
  88. data/lib/generated_definitions/vn.rb +1 -3
  89. data/lib/generated_definitions/za.rb +1 -3
  90. data/lib/holidays/{load_all_definitions.rb → bootstrap.rb} +15 -8
  91. data/lib/holidays/date_calculator/hijri_date.rb +52 -0
  92. data/lib/holidays/date_calculator/lunar_date.rb +2 -1
  93. data/lib/holidays/definition/context/generator.rb +4 -0
  94. data/lib/holidays/definition/context/merger.rb +6 -1
  95. data/lib/holidays/definition/custom_methods/ar.rb +28 -0
  96. data/lib/holidays/definition/custom_methods/au.rb +96 -0
  97. data/lib/holidays/definition/custom_methods/ca.rb +23 -0
  98. data/lib/holidays/definition/custom_methods/ch.rb +58 -0
  99. data/lib/holidays/definition/custom_methods/cl.rb +43 -0
  100. data/lib/holidays/definition/custom_methods/cn.rb +31 -0
  101. data/lib/holidays/definition/custom_methods/co.rb +22 -0
  102. data/lib/holidays/definition/custom_methods/de.rb +23 -0
  103. data/lib/holidays/definition/custom_methods/fedex.rb +17 -0
  104. data/lib/holidays/definition/custom_methods/fi.rb +35 -0
  105. data/lib/holidays/definition/custom_methods/ie.rb +22 -0
  106. data/lib/holidays/definition/custom_methods/is.rb +23 -0
  107. data/lib/holidays/definition/custom_methods/jp.rb +107 -0
  108. data/lib/holidays/definition/custom_methods/kr.rb +17 -0
  109. data/lib/holidays/definition/custom_methods/lv.rb +27 -0
  110. data/lib/holidays/definition/custom_methods/nz.rb +77 -0
  111. data/lib/holidays/definition/custom_methods/ph.rb +19 -0
  112. data/lib/holidays/definition/custom_methods/registry.rb +104 -0
  113. data/lib/holidays/definition/custom_methods/se.rb +25 -0
  114. data/lib/holidays/definition/custom_methods/tr.rb +68 -0
  115. data/lib/holidays/definition/custom_methods/us.rb +119 -0
  116. data/lib/holidays/definition/generator/module.rb +7 -4
  117. data/lib/holidays/definition/repository/proc_result_cache.rb +4 -0
  118. data/lib/holidays/factory/date_calculator.rb +6 -1
  119. data/lib/holidays/factory/definition.rb +2 -0
  120. data/lib/holidays/version.rb +1 -1
  121. data/lib/holidays.rb +4 -2
  122. metadata +25 -2
@@ -0,0 +1,22 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # ie custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/ie.yaml.
8
+ module IE
9
+ class << self
10
+ def ie_st_brigids_day(year)
11
+ date = Date.civil(year, 2, 1)
12
+ if date.wday == 5
13
+ date
14
+ else
15
+ date + ((1 - date.wday) % 7)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # is custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/is.yaml.
8
+ module IS
9
+ class << self
10
+ def is_sumardagurinn_fyrsti(year)
11
+ date = Date.civil(year,4,18)
12
+ if date.wday < 4
13
+ date += (4 - date.wday)
14
+ else
15
+ date += (11 - date.wday)
16
+ end
17
+ date
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,107 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # jp custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/jp.yaml.
8
+ module JP
9
+ class << self
10
+ def jp_health_sports_day_substitute(year)
11
+ Holidays::Factory::Definition.custom_methods_repository.find("jp_substitute_holiday(year, month, day)").call(year, 10, Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 10, 2, 1))
12
+ end
13
+
14
+ def jp_vernal_equinox_day(year)
15
+ day =
16
+ case year
17
+ when 1851..1899
18
+ 19.8277
19
+ when 1900..1979
20
+ 20.8357
21
+ when 1980..2099
22
+ 20.8431
23
+ when 2100..2150
24
+ 21.8510
25
+ else
26
+ raise IndexError.new("Out of range")
27
+ end
28
+ day += 0.242194 * (year - 1980) - ((year - 1980)/4).floor
29
+ day = day.floor
30
+ Date.civil(year, 3, day)
31
+ end
32
+
33
+ def jp_vernal_equinox_day_substitute(year)
34
+ date = Holidays::Factory::Definition.custom_methods_repository.find("jp_vernal_equinox_day(year)").call(year)
35
+ Holidays::Factory::Definition.custom_methods_repository.find("jp_substitute_holiday(year, month, day)").call(year, date.month, date.mday)
36
+ end
37
+
38
+ def jp_marine_day_substitute(year)
39
+ Holidays::Factory::Definition.custom_methods_repository.find("jp_substitute_holiday(year, month, day)").call(year, 7, Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 7, 3, 1))
40
+ end
41
+
42
+ def jp_national_culture_day(year)
43
+ day =
44
+ case year
45
+ when 1851..1899
46
+ 22.2588
47
+ when 1900..1979
48
+ 23.2588
49
+ when 1980..2099
50
+ 23.2488
51
+ when 2100..2150
52
+ 24.2488
53
+ else
54
+ raise IndexError.new("Out of range")
55
+ end
56
+ day += 0.242194 * (year - 1980) - ((year - 1980)/4).floor
57
+ day = day.floor
58
+ Date.civil(year, 9, day)
59
+ end
60
+
61
+ def jp_national_culture_day_substitute(year)
62
+ date = Holidays::Factory::Definition.custom_methods_repository.find("jp_national_culture_day(year)").call(year)
63
+ Holidays::Factory::Definition.custom_methods_repository.find("jp_substitute_holiday(year, month, day)").call(year, date.month, date.mday)
64
+ end
65
+
66
+ def jp_citizens_holiday(year)
67
+ ncd = Holidays::Factory::Definition.custom_methods_repository.find("jp_national_culture_day(year)").call(year)
68
+ if ncd.wday == 3
69
+ ncd - 1
70
+ else
71
+ nil
72
+ end
73
+ end
74
+
75
+ def jp_mountain_holiday(year)
76
+ Date.civil(year, 8, 11)
77
+ end
78
+
79
+ def jp_mountain_holiday_substitute(year)
80
+ date = Holidays::Factory::Definition.custom_methods_repository.find("jp_mountain_holiday(year)").call(year)
81
+ Holidays::Factory::Definition.custom_methods_repository.find("jp_substitute_holiday(year, month, day)").call(year, date.month, date.mday)
82
+ end
83
+
84
+ def jp_respect_for_aged_holiday_substitute(year)
85
+ Holidays::Factory::Definition.custom_methods_repository.find("jp_substitute_holiday(year, month, day)").call(year, 9, Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 9, 3, 1))
86
+ end
87
+
88
+ def jp_substitute_holiday(year, month, day)
89
+ date = Date.civil(year, month, day)
90
+ date.wday == 0 ? (Holidays::Factory::Definition.custom_methods_repository.find("jp_next_weekday(date)").call(date+1)) : nil
91
+ end
92
+
93
+ def jp_next_weekday(date)
94
+ # This suuuucks. I have no idea how to make this not reach into our interal ruby API to do this.
95
+ # I'm punting, I'll come back to this.
96
+ is_holiday = Holidays::JP.holidays_by_month[date.month].any? do |holiday|
97
+ next false unless holiday[:mday] == date.day
98
+ next true unless holiday[:year_ranges]
99
+ Holidays::Finder::Rules::YearRange.call(date.year, holiday[:year_ranges])
100
+ end
101
+ date.wday == 0 || is_holiday ? (Holidays::Factory::Definition.custom_methods_repository.find("jp_next_weekday(date)").call(date+1)) : date
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,17 @@
1
+ module Holidays
2
+ module Definition
3
+ module CustomMethods
4
+ # kr custom holiday calculations, ported verbatim from the
5
+ # +methods:+ block in definitions/kr.yaml.
6
+ module KR
7
+ class << self
8
+ # Seollal eve is the day before Seollal (Korean New Year), which is
9
+ # the first day of the first lunar month.
10
+ def kr_seollal_eve(year, region)
11
+ Holidays::Factory::Definition.custom_methods_repository.find("lunar_to_solar(year, month, day, region)").call(year, 1, 1, region) - 1
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # lv custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/lv.yaml.
8
+ module LV
9
+ class << self
10
+ def lv_song_and_dance_festival_end_date(year)
11
+ case year
12
+ when 2018
13
+ # https://likumi.lv/ta/id/281541 (Ministru kabineta rīkojums Nr. 252 "Par XXVI Vispārējo latviešu dziesmu un XVI Deju svētku norises laiku")
14
+ Date.new(2018, 7, 8)
15
+ when 2023
16
+ # https://likumi.lv/ta/id/330067 (Ministru kabineta rīkojums Nr. 92 "Par XXVII Vispārējo latviešu dziesmu un XVII Deju svētku norises laiku")
17
+ Date.new(2023, 7, 9)
18
+ when 2028
19
+ # Event's period/next year is known, but precise dates aren't.
20
+ # Previously, dates were announced 2 years ahead, so on ~2026-05 this method would need to be revisited.
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,77 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # nz custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/nz.yaml.
8
+ module NZ
9
+ class << self
10
+ def closest_monday(date)
11
+ if [1, 2, 3, 4].include?(date.wday)
12
+ date -= (date.wday - 1)
13
+ elsif 0 == date.wday
14
+ date += 1
15
+ else
16
+ date += 8 - date.wday
17
+ end
18
+ date
19
+ end
20
+
21
+ def previous_friday(date)
22
+ date - 3
23
+ end
24
+
25
+ def next_week(date)
26
+ date + 7
27
+ end
28
+
29
+ def nz_canterbury_anniversary(year)
30
+ date = Date.civil(year, 11, 1)
31
+ date += 1 until date.tuesday?
32
+ date += 1
33
+ date += 1 until date.friday?
34
+ date + 7
35
+ end
36
+
37
+ def matariki(year)
38
+ @matariki_dates ||= {
39
+ '2022' => Date.civil(2022, 6, 24),
40
+ '2023' => Date.civil(2023, 7, 14),
41
+ '2024' => Date.civil(2024, 6, 28),
42
+ '2025' => Date.civil(2025, 6, 20),
43
+ '2026' => Date.civil(2026, 7, 10),
44
+ '2027' => Date.civil(2027, 6, 25),
45
+ '2028' => Date.civil(2028, 7, 14),
46
+ '2029' => Date.civil(2029, 7, 6),
47
+ '2030' => Date.civil(2030, 6, 21),
48
+ '2031' => Date.civil(2031, 7, 11),
49
+ '2032' => Date.civil(2032, 7, 2),
50
+ '2033' => Date.civil(2033, 6, 24),
51
+ '2034' => Date.civil(2034, 7, 7),
52
+ '2035' => Date.civil(2035, 6, 29),
53
+ '2036' => Date.civil(2036, 7, 18),
54
+ '2037' => Date.civil(2037, 7, 10),
55
+ '2038' => Date.civil(2038, 6, 25),
56
+ '2039' => Date.civil(2039, 7, 15),
57
+ '2040' => Date.civil(2040, 7, 6),
58
+ '2041' => Date.civil(2041, 7, 19),
59
+ '2042' => Date.civil(2042, 7, 11),
60
+ '2043' => Date.civil(2043, 7, 3),
61
+ '2044' => Date.civil(2044, 6, 24),
62
+ '2045' => Date.civil(2045, 7, 7),
63
+ '2046' => Date.civil(2046, 6, 29),
64
+ '2047' => Date.civil(2047, 7, 19),
65
+ '2048' => Date.civil(2048, 7, 3),
66
+ '2049' => Date.civil(2049, 6, 25),
67
+ '2050' => Date.civil(2050, 7, 15),
68
+ '2051' => Date.civil(2051, 6, 30),
69
+ '2052' => Date.civil(2052, 6, 21),
70
+ }
71
+ @matariki_dates[year.to_s]
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,19 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # ph custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/ph.yaml.
8
+ module PH
9
+ class << self
10
+ def ph_heroes_day(year)
11
+ date = Date.new(year, 8, -1)
12
+ date -= (date.wday - 1) % 7
13
+ date
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,104 @@
1
+ require 'holidays/definition/custom_methods/ar'
2
+ require 'holidays/definition/custom_methods/au'
3
+ require 'holidays/definition/custom_methods/ca'
4
+ require 'holidays/definition/custom_methods/ch'
5
+ require 'holidays/definition/custom_methods/cn'
6
+ require 'holidays/definition/custom_methods/cl'
7
+ require 'holidays/definition/custom_methods/co'
8
+ require 'holidays/definition/custom_methods/de'
9
+ require 'holidays/definition/custom_methods/fedex'
10
+ require 'holidays/definition/custom_methods/fi'
11
+ require 'holidays/definition/custom_methods/ie'
12
+ require 'holidays/definition/custom_methods/is'
13
+ require 'holidays/definition/custom_methods/jp'
14
+ require 'holidays/definition/custom_methods/kr'
15
+ require 'holidays/definition/custom_methods/lv'
16
+ require 'holidays/definition/custom_methods/nz'
17
+ require 'holidays/definition/custom_methods/ph'
18
+ require 'holidays/definition/custom_methods/se'
19
+ require 'holidays/definition/custom_methods/tr'
20
+ require 'holidays/definition/custom_methods/us'
21
+
22
+ module Holidays
23
+ module Definition
24
+ module CustomMethods
25
+ # Maps the full call-signature string used by YAML +function:+/+observed:+
26
+ # references to the native proc that implements it. Seeded into
27
+ # Factory::Definition.custom_methods_repository at boot by
28
+ # Holidays::Bootstrap.call, alongside the global built-in methods.
29
+ #
30
+ # Native replacement for the old per-region +methods:/ruby:+ YAML blocks.
31
+ # No eval, no public registration API.
32
+ #
33
+ # ca_victoria_day and day_after_thanksgiving each have byte-identical
34
+ # duplicates in other region YAML files; hosted once here and shared.
35
+ def self.all
36
+ {
37
+ "afl_grand_final(year)" => AU.method(:afl_grand_final).to_proc,
38
+ "ca_victoria_day(year)" => CA.method(:ca_victoria_day).to_proc,
39
+ "ch_be_zibelemaerit(year)" => CH.method(:ch_be_zibelemaerit).to_proc,
40
+ "ch_ge_jeune_genevois(year)" => CH.method(:ch_ge_jeune_genevois).to_proc,
41
+ "ch_gl_naefelser_fahrt(year)" => CH.method(:ch_gl_naefelser_fahrt).to_proc,
42
+ "ch_vd_lundi_du_jeune_federal(year)" => CH.method(:ch_vd_lundi_du_jeune_federal).to_proc,
43
+ "christmas_eve_holiday(date)" => US.method(:christmas_eve_holiday).to_proc,
44
+ "closest_monday(date)" => NZ.method(:closest_monday).to_proc,
45
+ "cn_qingming(year)" => CN.method(:cn_qingming).to_proc,
46
+ "columbus_day_cl(year)" => CL.method(:columbus_day_cl).to_proc,
47
+ "day_after_thanksgiving(year)" => FEDEX.method(:day_after_thanksgiving).to_proc,
48
+ "de_buss_und_bettag(year)" => DE.method(:de_buss_und_bettag).to_proc,
49
+ "election_day(year)" => US.method(:election_day).to_proc,
50
+ "even_year_election_day(year)" => US.method(:even_year_election_day).to_proc,
51
+ "fi_juhannusaatto(year)" => FI.method(:fi_juhannusaatto).to_proc,
52
+ "fi_juhannuspaiva(year)" => FI.method(:fi_juhannuspaiva).to_proc,
53
+ "fi_pyhainpaiva(year)" => FI.method(:fi_pyhainpaiva).to_proc,
54
+ "georgia_state_holiday(year, month)" => US.method(:georgia_state_holiday).to_proc,
55
+ "hobart_show_day(year)" => AU.method(:hobart_show_day).to_proc,
56
+ "ie_st_brigids_day(year)" => IE.method(:ie_st_brigids_day).to_proc,
57
+ "independence_day(region, date)" => US.method(:independence_day).to_proc,
58
+ "is_sumardagurinn_fyrsti(year)" => IS.method(:is_sumardagurinn_fyrsti).to_proc,
59
+ "jp_citizens_holiday(year)" => JP.method(:jp_citizens_holiday).to_proc,
60
+ "jp_health_sports_day_substitute(year)" => JP.method(:jp_health_sports_day_substitute).to_proc,
61
+ "jp_marine_day_substitute(year)" => JP.method(:jp_marine_day_substitute).to_proc,
62
+ "jp_mountain_holiday(year)" => JP.method(:jp_mountain_holiday).to_proc,
63
+ "jp_mountain_holiday_substitute(year)" => JP.method(:jp_mountain_holiday_substitute).to_proc,
64
+ "jp_national_culture_day(year)" => JP.method(:jp_national_culture_day).to_proc,
65
+ "jp_national_culture_day_substitute(year)" => JP.method(:jp_national_culture_day_substitute).to_proc,
66
+ "jp_next_weekday(date)" => JP.method(:jp_next_weekday).to_proc,
67
+ "jp_respect_for_aged_holiday_substitute(year)" => JP.method(:jp_respect_for_aged_holiday_substitute).to_proc,
68
+ "jp_substitute_holiday(year, month, day)" => JP.method(:jp_substitute_holiday).to_proc,
69
+ "jp_vernal_equinox_day(year)" => JP.method(:jp_vernal_equinox_day).to_proc,
70
+ "jp_vernal_equinox_day_substitute(year)" => JP.method(:jp_vernal_equinox_day_substitute).to_proc,
71
+ "juneteenth_national_independence_day(region, date)" => US.method(:juneteenth_national_independence_day).to_proc,
72
+ "kr_seollal_eve(year, region)" => KR.method(:kr_seollal_eve).to_proc,
73
+ "lee_jackson_day(year, month)" => US.method(:lee_jackson_day).to_proc,
74
+ "lv_song_and_dance_festival_end_date(year)" => LV.method(:lv_song_and_dance_festival_end_date).to_proc,
75
+ "march_pub_hol_sa(year)" => AU.method(:march_pub_hol_sa).to_proc,
76
+ "matariki(year)" => NZ.method(:matariki).to_proc,
77
+ "may_pub_hol_sa(year)" => AU.method(:may_pub_hol_sa).to_proc,
78
+ "next_week(date)" => NZ.method(:next_week).to_proc,
79
+ "nz_canterbury_anniversary(year)" => NZ.method(:nz_canterbury_anniversary).to_proc,
80
+ "other_churches_day_cl(year)" => CL.method(:other_churches_day_cl).to_proc,
81
+ "ph_heroes_day(year)" => PH.method(:ph_heroes_day).to_proc,
82
+ "previous_friday(date)" => NZ.method(:previous_friday).to_proc,
83
+ "qld_brisbane_ekka_holiday(year)" => AU.method(:qld_brisbane_ekka_holiday).to_proc,
84
+ "qld_kings_bday_october(year)" => AU.method(:qld_kings_bday_october).to_proc,
85
+ "qld_labour_day_may(year)" => AU.method(:qld_labour_day_may).to_proc,
86
+ "qld_labour_day_october(year)" => AU.method(:qld_labour_day_october).to_proc,
87
+ "qld_queens_bday_october(year)" => AU.method(:qld_queens_bday_october).to_proc,
88
+ "qld_queens_birthday_june(year)" => AU.method(:qld_queens_birthday_june).to_proc,
89
+ "ramadan_feast(year)" => TR.method(:ramadan_feast).to_proc,
90
+ "rosh_hashanah(year)" => US.method(:rosh_hashanah).to_proc,
91
+ "sacrifice_feast(year)" => TR.method(:sacrifice_feast).to_proc,
92
+ "se_alla_helgons_dag(year)" => SE.method(:se_alla_helgons_dag).to_proc,
93
+ "se_midsommardagen(year)" => SE.method(:se_midsommardagen).to_proc,
94
+ "st_peter_st_paul_cl(year)" => CL.method(:st_peter_st_paul_cl).to_proc,
95
+ "to_following_monday_if_not_monday(date)" => CO.method(:to_following_monday_if_not_monday).to_proc,
96
+ "to_nearest_monday(date)" => AR.method(:to_nearest_monday).to_proc,
97
+ "to_nearest_monday_after(date)" => AU.method(:to_nearest_monday_after).to_proc,
98
+ "us_inauguration_day(year)" => US.method(:us_inauguration_day).to_proc,
99
+ "yom_kippur(year)" => US.method(:yom_kippur).to_proc,
100
+ }
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,25 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # se custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/se.yaml.
8
+ module SE
9
+ class << self
10
+ def se_midsommardagen(year)
11
+ date = Date.civil(year,6,20)
12
+ date += (6 - date.wday)
13
+ date
14
+ end
15
+
16
+ def se_alla_helgons_dag(year)
17
+ date = Date.civil(year,10,31)
18
+ date += (6 - date.wday)
19
+ date
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,68 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # tr custom holiday calculations.
7
+ #
8
+ # Ramazan Bayramı is 1 Shawwal and Kurban Bayramı is 10 Dhul-Hijjah of
9
+ # the Hijri calendar. Both are derived from the arithmetic Islamic
10
+ # calendar (Holidays::DateCalculator::HijriDate). The civil holidays are
11
+ # proclaimed by Türkiye's Diyanet and in most years so far have landed a
12
+ # day (2016 Ramazan Bayramı, two days) before the arithmetic result;
13
+ # DIYANET_OVERRIDES pins those years to the proclaimed date. Years with
14
+ # no entry fall back to the calculation. See definitions#377.
15
+ module TR
16
+ SHAWWAL = 10
17
+ DHU_AL_HIJJAH = 12
18
+
19
+ # Proclaimed first days that differ from the arithmetic calendar,
20
+ # keyed by [feast, gregorian_year]. Sourced from the Diyanet dates
21
+ # that the definition file previously carried as a fixed table, plus
22
+ # https://vakithesaplama.diyanet.gov.tr/resmitatiller.php for 2021-2030.
23
+ DIYANET_OVERRIDES = {
24
+ [:ramadan_feast, 2014] => Date.new(2014, 7, 28),
25
+ [:ramadan_feast, 2015] => Date.new(2015, 7, 17),
26
+ [:ramadan_feast, 2016] => Date.new(2016, 7, 5),
27
+ [:ramadan_feast, 2017] => Date.new(2017, 6, 25),
28
+ [:ramadan_feast, 2019] => Date.new(2019, 6, 4),
29
+ [:ramadan_feast, 2022] => Date.new(2022, 5, 2),
30
+ [:ramadan_feast, 2023] => Date.new(2023, 4, 21),
31
+ [:ramadan_feast, 2025] => Date.new(2025, 3, 30),
32
+ [:ramadan_feast, 2027] => Date.new(2027, 3, 9),
33
+ [:ramadan_feast, 2028] => Date.new(2028, 2, 26),
34
+ [:ramadan_feast, 2030] => Date.new(2030, 2, 4),
35
+
36
+ [:sacrifice_feast, 2014] => Date.new(2014, 10, 4),
37
+ [:sacrifice_feast, 2016] => Date.new(2016, 9, 12),
38
+ [:sacrifice_feast, 2017] => Date.new(2017, 9, 1),
39
+ [:sacrifice_feast, 2018] => Date.new(2018, 8, 21),
40
+ [:sacrifice_feast, 2019] => Date.new(2019, 8, 11),
41
+ [:sacrifice_feast, 2022] => Date.new(2022, 7, 9),
42
+ [:sacrifice_feast, 2023] => Date.new(2023, 6, 28),
43
+ [:sacrifice_feast, 2024] => Date.new(2024, 6, 16),
44
+ [:sacrifice_feast, 2025] => Date.new(2025, 6, 6),
45
+ [:sacrifice_feast, 2027] => Date.new(2027, 5, 16),
46
+ [:sacrifice_feast, 2030] => Date.new(2030, 4, 13),
47
+ }.freeze
48
+
49
+ class << self
50
+ def ramadan_feast(year)
51
+ feast(:ramadan_feast, year, SHAWWAL, 1)
52
+ end
53
+
54
+ def sacrifice_feast(year)
55
+ feast(:sacrifice_feast, year, DHU_AL_HIJJAH, 10)
56
+ end
57
+
58
+ private
59
+
60
+ def feast(name, year, hijri_month, hijri_day)
61
+ DIYANET_OVERRIDES[[name, year]] ||
62
+ Holidays::Factory::DateCalculator.hijri_date.gregorian_year_occurrence(year, hijri_month, hijri_day)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,119 @@
1
+ require 'date'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module CustomMethods
6
+ # us custom holiday calculations, ported verbatim from the
7
+ # +methods:+ block in definitions/us.yaml.
8
+ module US
9
+ class << self
10
+ def christmas_eve_holiday(date)
11
+ beginning_of_month = Date.civil(date.year, date.month, 1)
12
+ (date.saturday? || date.sunday?) ? date.downto(beginning_of_month).find {|d| d if d.wday == 5} : date
13
+ end
14
+
15
+ def rosh_hashanah(year)
16
+ rosh_hashanah_dates = {
17
+ '2014' => Date.civil(2014, 9, 25),
18
+ '2015' => Date.civil(2015, 9, 14),
19
+ '2016' => Date.civil(2016, 10, 3),
20
+ '2017' => Date.civil(2017, 9, 21),
21
+ '2018' => Date.civil(2018, 9, 10),
22
+ '2019' => Date.civil(2019, 9, 30),
23
+ '2020' => Date.civil(2020, 9, 19)
24
+ }
25
+ rosh_hashanah_dates[year.to_s]
26
+ end
27
+
28
+ def yom_kippur(year)
29
+ yom_kippur_dates = {
30
+ '2014' => Date.civil(2014, 10, 4),
31
+ '2015' => Date.civil(2015, 9, 23),
32
+ '2016' => Date.civil(2016, 10, 12),
33
+ '2017' => Date.civil(2017, 9, 30),
34
+ '2018' => Date.civil(2018, 9, 19),
35
+ '2019' => Date.civil(2019, 10, 9),
36
+ '2020' => Date.civil(2020, 9, 28)
37
+ }
38
+ yom_kippur_dates[year.to_s]
39
+ end
40
+
41
+ def georgia_state_holiday(year, month)
42
+ beginning_of_month = Date.civil(year, month, 1)
43
+ state_holiday = Date.civil(year, month, 26)
44
+ state_holiday.downto(beginning_of_month).find {|date| date if date.wday == 1 }
45
+ end
46
+
47
+ def lee_jackson_day(year, month)
48
+ day_of_holiday = Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, month, 3, 1)
49
+ beginning_of_month = Date.civil(year, month, 1)
50
+ king_day = Date.civil(year, month, day_of_holiday)
51
+ king_day.downto(beginning_of_month).find {|date| date if date.wday == 5 }
52
+ end
53
+
54
+ def juneteenth_national_independence_day(region, date)
55
+ if region == :us_ut
56
+ case date.wday
57
+ when 1
58
+ date
59
+ when 2,3,4,5
60
+ date - (date.wday - 1)
61
+ when 6
62
+ date + 2
63
+ when 0
64
+ date + 1
65
+ end
66
+ elsif date.wday == 0
67
+ date + 1
68
+ elsif date.wday == 6
69
+ date - 1
70
+ else
71
+ date
72
+ end
73
+ end
74
+
75
+ # Independence Day observed shift, which varies by region:
76
+ # - us_ri: Rhode Island moves to the following Monday on a weekend
77
+ # (Saturday -> +2, Sunday -> +1).
78
+ # - us_tx: Texas does not shift, the date is returned unchanged.
79
+ # - everyone else: nearest weekday, same as +to_weekday_if_weekend+
80
+ # (Saturday -> Friday, Sunday -> Monday).
81
+ def independence_day(region, date)
82
+ if region == :us_ri
83
+ case date.wday
84
+ when 6
85
+ date + 2
86
+ when 0
87
+ date + 1
88
+ else
89
+ date
90
+ end
91
+ elsif region == :us_tx
92
+ date
93
+ elsif date.wday == 6
94
+ date - 1
95
+ elsif date.wday == 0
96
+ date + 1
97
+ else
98
+ date
99
+ end
100
+ end
101
+
102
+ def election_day(year)
103
+ Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 11, 1, 1) + 1
104
+ end
105
+
106
+ def even_year_election_day(year)
107
+ if year % 2 == 0
108
+ Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 11, 1, 1) + 1
109
+ end
110
+ end
111
+
112
+ def us_inauguration_day(year)
113
+ year % 4 == 1 ? 20 : nil
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -4,7 +4,12 @@ module Holidays
4
4
  module Definition
5
5
  module Generator
6
6
  class Module
7
- def call(module_name, files, regions, month_strings, custom_methods)
7
+ # NOTE: +custom_methods+ is accepted for backwards-compatible call sites but is
8
+ # no longer baked into the generated module. Per-region custom methods are now
9
+ # hosted natively under lib/holidays/definition/custom_methods/ and seeded into
10
+ # the repository at boot. YAML files that still carry methods:/ruby: blocks are
11
+ # tolerated: their bodies are simply ignored here.
12
+ def call(module_name, files, regions, month_strings, custom_methods = nil)
8
13
  raise ArgumentError.new("module name cannot be nil") if module_name.nil?
9
14
  raise ArgumentError.new("module name cannot be blank") if module_name.empty?
10
15
 
@@ -38,9 +43,7 @@ module Holidays
38
43
  end
39
44
 
40
45
  def self.custom_methods
41
- {
42
- #{custom_methods}
43
- }
46
+ {}
44
47
  end
45
48
  end
46
49
  end
@@ -33,6 +33,10 @@ module Holidays
33
33
  @proc_cache[proc_key]
34
34
  end
35
35
 
36
+ def reset!
37
+ @proc_cache = {}
38
+ end
39
+
36
40
  private
37
41
 
38
42
  def validate!(function, function_arguments)