holidays 6.4.0 → 8.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitmodules +1 -1
- data/CHANGELOG.md +80 -0
- data/Makefile +17 -4
- data/README.md +236 -101
- data/Rakefile +1 -1
- data/bin/console +0 -0
- data/bin/setup +1 -0
- data/doc/CONTRIBUTING.md +72 -0
- data/{MAINTAINERS.md → doc/MAINTAINERS.md} +5 -6
- data/{REFERENCES → doc/REFERENCES} +0 -0
- data/holidays.gemspec +8 -9
- data/lib/generated_definitions/MANIFEST +12 -4
- data/lib/generated_definitions/REGIONS.rb +2 -2
- data/lib/generated_definitions/ar.rb +30 -11
- data/lib/generated_definitions/at.rb +2 -2
- data/lib/generated_definitions/au.rb +26 -8
- data/lib/generated_definitions/be_fr.rb +2 -2
- data/lib/generated_definitions/be_nl.rb +2 -2
- data/lib/generated_definitions/bg.rb +2 -2
- data/lib/generated_definitions/br.rb +2 -2
- data/lib/generated_definitions/ca.rb +24 -17
- data/lib/generated_definitions/ch.rb +16 -4
- data/lib/generated_definitions/cl.rb +7 -10
- data/lib/generated_definitions/co.rb +121 -0
- data/lib/generated_definitions/cr.rb +2 -2
- data/lib/generated_definitions/cz.rb +2 -2
- data/lib/generated_definitions/de.rb +8 -5
- data/lib/generated_definitions/dk.rb +2 -2
- data/lib/generated_definitions/{ecb_target.rb → ecbtarget.rb} +10 -10
- data/lib/generated_definitions/ee.rb +2 -2
- data/lib/generated_definitions/el.rb +2 -2
- data/lib/generated_definitions/es.rb +8 -5
- data/lib/generated_definitions/europe.rb +114 -29
- data/lib/generated_definitions/federalreserve.rb +35 -0
- data/lib/generated_definitions/{federal_reserve.rb → federalreservebanks.rb} +15 -14
- data/lib/generated_definitions/fedex.rb +2 -2
- data/lib/generated_definitions/fi.rb +2 -2
- data/lib/generated_definitions/fr.rb +2 -2
- data/lib/generated_definitions/gb.rb +15 -8
- data/lib/generated_definitions/ge.rb +2 -2
- data/lib/generated_definitions/hk.rb +2 -2
- data/lib/generated_definitions/hr.rb +10 -8
- data/lib/generated_definitions/hu.rb +4 -3
- data/lib/generated_definitions/ie.rb +2 -2
- data/lib/generated_definitions/is.rb +2 -2
- data/lib/generated_definitions/it.rb +16 -7
- data/lib/generated_definitions/jp.rb +34 -15
- data/lib/generated_definitions/kr.rb +2 -2
- data/lib/generated_definitions/kz.rb +38 -0
- data/lib/generated_definitions/li.rb +2 -2
- data/lib/generated_definitions/lt.rb +2 -2
- data/lib/generated_definitions/lu.rb +4 -2
- data/lib/generated_definitions/lv.rb +55 -0
- data/lib/generated_definitions/ma.rb +2 -2
- data/lib/generated_definitions/mt_en.rb +2 -2
- data/lib/generated_definitions/mt_mt.rb +2 -2
- data/lib/generated_definitions/mx.rb +7 -7
- data/lib/generated_definitions/my.rb +2 -2
- data/lib/generated_definitions/nerc.rb +2 -2
- data/lib/generated_definitions/ng.rb +33 -0
- data/lib/generated_definitions/nl.rb +2 -2
- data/lib/generated_definitions/no.rb +2 -2
- data/lib/generated_definitions/{north_america.rb → northamerica.rb} +33 -26
- data/lib/generated_definitions/nyse.rb +3 -2
- data/lib/generated_definitions/nz.rb +41 -3
- data/lib/generated_definitions/pe.rb +2 -2
- data/lib/generated_definitions/ph.rb +2 -2
- data/lib/generated_definitions/pl.rb +2 -2
- data/lib/generated_definitions/pt.rb +2 -2
- data/lib/generated_definitions/ro.rb +6 -3
- data/lib/generated_definitions/rs_cyrl.rb +3 -3
- data/lib/generated_definitions/rs_la.rb +3 -3
- data/lib/generated_definitions/ru.rb +2 -2
- data/lib/generated_definitions/scandinavia.rb +2 -2
- data/lib/generated_definitions/se.rb +2 -2
- data/lib/generated_definitions/sg.rb +2 -2
- data/lib/generated_definitions/si.rb +4 -3
- data/lib/generated_definitions/sk.rb +2 -2
- data/lib/generated_definitions/southamerica.rb +247 -0
- data/lib/generated_definitions/th.rb +36 -0
- data/lib/generated_definitions/tn.rb +2 -2
- data/lib/generated_definitions/tr.rb +7 -5
- data/lib/generated_definitions/ua.rb +37 -0
- data/lib/generated_definitions/{united_nations.rb → unitednations.rb} +61 -61
- data/lib/generated_definitions/ups.rb +2 -2
- data/lib/generated_definitions/us.rb +9 -9
- data/lib/generated_definitions/ve.rb +2 -2
- data/lib/generated_definitions/vi.rb +2 -2
- data/lib/generated_definitions/za.rb +3 -3
- data/lib/holidays/core_extensions/time.rb +3 -3
- data/lib/holidays/definition/context/generator.rb +23 -70
- data/lib/holidays/definition/context/load.rb +1 -1
- data/lib/holidays/definition/generator/module.rb +54 -0
- data/lib/holidays/definition/generator/regions.rb +7 -2
- data/lib/holidays/definition/parser/custom_method.rb +2 -2
- data/lib/holidays/definition/repository/cache.rb +2 -1
- data/lib/holidays/definition/repository/holidays_by_month.rb +9 -1
- data/lib/holidays/factory/definition.rb +7 -0
- data/lib/holidays/finder/context/between.rb +6 -7
- data/lib/holidays/finder/context/dates_driver_builder.rb +5 -11
- data/lib/holidays/finder/context/next_holiday.rb +12 -12
- data/lib/holidays/finder/context/parse_options.rb +0 -6
- data/lib/holidays/finder/context/search.rb +39 -32
- data/lib/holidays/finder/rules/year_range.rb +30 -54
- data/lib/holidays/version.rb +1 -1
- data/lib/holidays.rb +14 -7
- data/test/coverage_report.rb +23 -7
- data/test/data/test_custom_informal_holidays_defs.yaml +11 -0
- data/test/data/test_custom_year_range_holiday_defs.yaml +6 -10
- data/test/data/test_multiple_regions_with_conflicts_region_1.yaml +38 -0
- data/test/data/test_multiple_regions_with_conflicts_region_2.yaml +38 -0
- data/test/defs/test_defs_ar.rb +30 -6
- data/test/defs/test_defs_at.rb +5 -3
- data/test/defs/test_defs_au.rb +29 -0
- data/test/defs/test_defs_be_fr.rb +10 -0
- data/test/defs/test_defs_be_nl.rb +10 -0
- data/test/defs/test_defs_ca.rb +63 -8
- data/test/defs/test_defs_ch.rb +6 -0
- data/test/defs/test_defs_co.rb +113 -0
- data/test/defs/test_defs_de.rb +7 -1
- data/test/defs/{test_defs_ecb_target.rb → test_defs_ecbtarget.rb} +11 -11
- data/test/defs/test_defs_es.rb +2 -0
- data/test/defs/test_defs_europe.rb +250 -15
- data/test/defs/test_defs_federalreserve.rb +119 -0
- data/test/defs/test_defs_federalreservebanks.rb +251 -0
- data/test/defs/test_defs_gb.rb +42 -0
- data/test/defs/test_defs_hr.rb +6 -6
- data/test/defs/test_defs_hu.rb +12 -4
- data/test/defs/test_defs_it.rb +20 -0
- data/test/defs/test_defs_jp.rb +30 -2
- data/test/defs/test_defs_kz.rb +39 -0
- data/test/defs/test_defs_lu.rb +6 -0
- data/test/defs/test_defs_lv.rb +96 -0
- data/test/defs/test_defs_mx.rb +3 -1
- data/test/defs/test_defs_ng.rb +29 -0
- data/test/defs/{test_defs_north_america.rb → test_defs_northamerica.rb} +77 -20
- data/test/defs/test_defs_nyse.rb +7 -0
- data/test/defs/test_defs_nz.rb +4 -0
- data/test/defs/test_defs_ro.rb +14 -0
- data/test/defs/test_defs_rs_cyrl.rb +1 -1
- data/test/defs/test_defs_rs_la.rb +1 -1
- data/test/defs/test_defs_southamerica.rb +323 -0
- data/test/defs/test_defs_th.rb +33 -0
- data/test/defs/test_defs_tr.rb +7 -0
- data/test/defs/test_defs_ua.rb +41 -0
- data/test/defs/{test_defs_united_nations.rb → test_defs_unitednations.rb} +3 -3
- data/test/defs/test_defs_us.rb +11 -11
- data/test/holidays/core_extensions/test_date.rb +3 -2
- data/test/holidays/definition/context/test_generator.rb +17 -20
- data/test/holidays/definition/context/test_load.rb +3 -3
- data/test/holidays/definition/generator/test_module.rb +268 -0
- data/test/holidays/definition/parser/test_custom_method.rb +4 -4
- data/test/holidays/definition/repository/test_holidays_by_month.rb +121 -1
- data/test/holidays/finder/context/test_parse_options.rb +0 -10
- data/test/holidays/finder/rules/test_year_range.rb +43 -47
- data/test/integration/test_any_holidays_during_work_week.rb +90 -0
- data/test/integration/test_available_regions.rb +1 -1
- data/test/integration/test_custom_informal_holidays.rb +15 -0
- data/test/integration/test_custom_year_range_holidays.rb +0 -7
- data/test/integration/test_holidays.rb +4 -56
- data/test/integration/test_holidays_between.rb +11 -1
- data/test/integration/test_multiple_regions.rb +54 -6
- data/test/integration/test_multiple_regions_with_conflict.rb +29 -0
- data/test/integration/test_nonstandard_regions.rb +25 -0
- metadata +79 -53
- data/CONTRIBUTING.md +0 -51
- data/test/defs/test_defs_federal_reserve.rb +0 -111
@@ -2,17 +2,17 @@
|
|
2
2
|
module Holidays
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
4
4
|
#
|
5
|
-
# Definitions loaded: definitions/us.yaml, definitions/
|
5
|
+
# Definitions loaded: definitions/us.yaml, definitions/northamericainformal.yaml
|
6
6
|
#
|
7
7
|
# All the definitions are available at https://github.com/holidays/holidays
|
8
8
|
module US # :nodoc:
|
9
9
|
def self.defined_regions
|
10
|
-
[:us_fl, :us_la, :us, :us_ct, :us_de, :us_gu, :us_hi, :us_in, :us_ky, :us_nj, :us_nc, :us_nd, :us_pr, :us_tn, :us_ms, :us_id, :us_ar, :us_tx, :us_dc, :us_md, :us_va, :
|
10
|
+
[:us_fl, :us_la, :us, :us_ct, :us_de, :us_gu, :us_hi, :us_in, :us_ky, :us_nj, :us_nc, :us_nd, :us_pr, :us_tn, :us_ms, :us_id, :us_ar, :us_tx, :us_dc, :us_md, :us_va, :us_vt, :us_ak, :us_ca, :us_me, :us_ma, :us_al, :us_ga, :us_ne, :us_mo, :us_sc, :us_wv, :us_vi, :us_ut, :us_ri, :us_az, :us_co, :us_il, :us_mt, :us_nm, :us_ny, :us_oh, :us_pa, :us_mi, :us_mn, :us_nv, :us_or, :us_sd, :us_wa, :us_wi, :us_wy, :us_ia, :us_ks, :us_nh, :us_ok, :ca]
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.holidays_by_month
|
14
14
|
{
|
15
|
-
|
15
|
+
0 => [{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -47, :name => "Shrove Tuesday", :regions => [:us_fl]},
|
16
16
|
{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -47, :name => "Mardi Gras Day", :regions => [:us_la]},
|
17
17
|
{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -2, :type => :informal, :name => "Good Friday", :regions => [:us]},
|
18
18
|
{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -2, :name => "Good Friday", :regions => [:us_ct, :us_de, :us_gu, :us_hi, :us_in, :us_ky, :us_la, :us_nj, :us_nc, :us_nd, :us_pr, :us_tn]},
|
@@ -28,14 +28,13 @@ module Holidays
|
|
28
28
|
2 => [{:wday => 1, :week => 3, :name => "Presidents' Day", :regions => [:us]},
|
29
29
|
{:mday => 2, :type => :informal, :name => "Groundhog Day", :regions => [:us, :ca]},
|
30
30
|
{:mday => 14, :type => :informal, :name => "Valentine's Day", :regions => [:us, :ca]}],
|
31
|
-
3 => [{:wday =>
|
32
|
-
{:wday => 2, :week => 1, :name => "Town Meeting Day", :regions => [:us_vt]},
|
31
|
+
3 => [{:wday => 2, :week => 1, :name => "Town Meeting Day", :regions => [:us_vt]},
|
33
32
|
{:mday => 2, :name => "Texas Independence Day", :regions => [:us_tx]},
|
34
33
|
{:mday => 26, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Prince Jonah Kuhio Kalanianaole Day", :regions => [:us_hi]},
|
35
34
|
{:wday => 1, :week => -1, :name => "Seward's Day", :regions => [:us_ak]},
|
36
35
|
{:mday => 31, :name => "César Chávez Day", :regions => [:us_ca]},
|
37
36
|
{:mday => 17, :type => :informal, :name => "St. Patrick's Day", :regions => [:us, :ca]}],
|
38
|
-
4 => [{:mday => 16, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Emancipation Day", :regions => [:us_dc
|
37
|
+
4 => [{:mday => 16, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Emancipation Day", :regions => [:us_dc]},
|
39
38
|
{:wday => 1, :week => 3, :name => "Patriots' Day", :regions => [:us_me, :us_ma]},
|
40
39
|
{:mday => 21, :name => "San Jacinto Day", :regions => [:us_tx]},
|
41
40
|
{:wday => 1, :week => -1, :name => "Confederate Memorial Day", :regions => [:us_al, :us_ms]},
|
@@ -52,6 +51,7 @@ module Holidays
|
|
52
51
|
6 => [{:wday => 1, :week => 1, :name => "Jefferson Davis' Birthday", :regions => [:us_al]},
|
53
52
|
{:mday => 3, :name => "Birthday of Jefferson Davis", :regions => [:us_fl]},
|
54
53
|
{:mday => 11, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "King Kamehameha I Day", :regions => [:us_hi]},
|
54
|
+
{:mday => 19, :year_ranges => { :from => 2021 },:observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Juneteenth National Independence Day", :regions => [:us]},
|
55
55
|
{:mday => 19, :name => "Emancipation Day in Texas", :regions => [:us_tx]},
|
56
56
|
{:mday => 20, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "West Virginia Day", :regions => [:us_wv]},
|
57
57
|
{:wday => 0, :week => 3, :type => :informal, :name => "Father's Day", :regions => [:us, :ca]}],
|
@@ -71,7 +71,7 @@ module Holidays
|
|
71
71
|
{:mday => 18, :name => "Alaska Day", :regions => [:us_ak]},
|
72
72
|
{:wday => 5, :week => -1, :name => "Nevada Day", :regions => [:us_nv]},
|
73
73
|
{:mday => 31, :type => :informal, :name => "Halloween", :regions => [:us, :ca]}],
|
74
|
-
11 => [{:function => "election_day(year)", :function_arguments => [:year], :name => "Election Day", :regions => [:us_de, :us_hi, :
|
74
|
+
11 => [{:function => "election_day(year)", :function_arguments => [:year], :name => "Election Day", :regions => [:us_de, :us_hi, :us_in, :us_mt, :us_nj, :us_ny, :us_pa, :us_ri]},
|
75
75
|
{:mday => 11, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Veterans Day", :regions => [:us]},
|
76
76
|
{:wday => 4, :week => 4, :name => "Thanksgiving", :regions => [:us]},
|
77
77
|
{:function => "day_after_thanksgiving(year)", :function_arguments => [:year], :name => "Family Day", :regions => [:us_nv]},
|
@@ -82,7 +82,7 @@ module Holidays
|
|
82
82
|
{:function => "day_after_thanksgiving(year)", :function_arguments => [:year], :name => "Day after Thanksgiving (Black Friday)", :regions => [:us_ca, :us_de, :us_fl, :us_ia, :us_il, :us_ks, :us_ky, :us_me, :us_mi, :us_mn, :us_ms, :us_ne, :us_nh, :us_nc, :us_pa, :us_sc, :us_ok, :us_tn, :us_tx, :us_va, :us_wa, :us_wv]}],
|
83
83
|
12 => [{:mday => 24, :name => "Christmas Eve", :regions => [:us_ar, :us_mi, :us_nc, :us_sc, :us_tx, :us_wi]},
|
84
84
|
{:mday => 24, :function => "christmas_eve_holiday(date)", :function_arguments => [:date], :name => "Christmas Eve (Holiday)", :regions => [:us_mi, :us_sc, :us_va]},
|
85
|
-
{:mday => 25, :observed => "
|
85
|
+
{:mday => 25, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Christmas Day", :regions => [:us]},
|
86
86
|
{:mday => 26, :name => "Day after Christmas", :regions => [:us_ar, :us_nc, :us_ok, :us_sc, :us_tn, :us_tx]},
|
87
87
|
{:mday => 31, :name => "New Year's Eve", :regions => [:us_mi, :us_wi]}]
|
88
88
|
}
|
@@ -90,7 +90,7 @@ module Holidays
|
|
90
90
|
|
91
91
|
def self.custom_methods
|
92
92
|
{
|
93
|
-
|
93
|
+
"christmas_eve_holiday(date)" => Proc.new { |date|
|
94
94
|
beginning_of_month = Date.civil(date.year, date.month, 1)
|
95
95
|
(date.saturday? || date.sunday?) ? date.downto(beginning_of_month).find {|d| d if d.wday == 5} : date
|
96
96
|
},
|
@@ -12,7 +12,7 @@ module Holidays
|
|
12
12
|
|
13
13
|
def self.holidays_by_month
|
14
14
|
{
|
15
|
-
|
15
|
+
0 => [{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -48, :name => "Lunes Carnaval", :regions => [:ve]},
|
16
16
|
{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -47, :name => "Martes Carnaval", :regions => [:ve]},
|
17
17
|
{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -3, :name => "Jueves Santo", :regions => [:ve]},
|
18
18
|
{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -2, :name => "Viernes Santo", :regions => [:ve]}],
|
@@ -29,7 +29,7 @@ module Holidays
|
|
29
29
|
|
30
30
|
def self.custom_methods
|
31
31
|
{
|
32
|
-
|
32
|
+
|
33
33
|
}
|
34
34
|
end
|
35
35
|
end
|
@@ -12,7 +12,7 @@ module Holidays
|
|
12
12
|
|
13
13
|
def self.holidays_by_month
|
14
14
|
{
|
15
|
-
|
15
|
+
1 => [{:mday => 1, :name => "Tết dương lịch", :regions => [:vi]}],
|
16
16
|
3 => [{:mday => 10, :function => "lunar_to_solar(year, month, day, region)", :function_arguments => [:year, :month, :day, :region], :name => "Giỗ tổ Hùng Vương", :regions => [:vi]}],
|
17
17
|
4 => [{:mday => 30, :name => "Ngày Giải phóng miền Nam, thống nhất đất nước", :regions => [:vi]}],
|
18
18
|
5 => [{:mday => 1, :name => "Ngày Quốc tế Lao động", :regions => [:vi]}],
|
@@ -22,7 +22,7 @@ module Holidays
|
|
22
22
|
|
23
23
|
def self.custom_methods
|
24
24
|
{
|
25
|
-
|
25
|
+
|
26
26
|
}
|
27
27
|
end
|
28
28
|
end
|
@@ -12,7 +12,7 @@ module Holidays
|
|
12
12
|
|
13
13
|
def self.holidays_by_month
|
14
14
|
{
|
15
|
-
|
15
|
+
0 => [{:function => "easter(year)", :function_arguments => [:year], :function_modifier => -2, :name => "Good Friday", :regions => [:za]},
|
16
16
|
{:function => "easter(year)", :function_arguments => [:year], :function_modifier => 1, :name => "Family Day", :regions => [:za]}],
|
17
17
|
1 => [{:mday => 1, :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "New Year's Day", :regions => [:za]}],
|
18
18
|
3 => [{:mday => 21, :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "Human Rights Day", :regions => [:za]}],
|
@@ -23,13 +23,13 @@ module Holidays
|
|
23
23
|
9 => [{:mday => 24, :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "Heritage Day", :regions => [:za]}],
|
24
24
|
12 => [{:mday => 16, :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "Day of Reconciliation", :regions => [:za]},
|
25
25
|
{:mday => 25, :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "Christmas Day", :regions => [:za]},
|
26
|
-
{:mday => 26, :observed => "
|
26
|
+
{:mday => 26, :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "Day of Goodwill", :regions => [:za]}]
|
27
27
|
}
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.custom_methods
|
31
31
|
{
|
32
|
-
|
32
|
+
|
33
33
|
}
|
34
34
|
end
|
35
35
|
end
|
@@ -4,7 +4,7 @@ module Holidays
|
|
4
4
|
def self.included(base)
|
5
5
|
base.extend ClassMethods
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
module ClassMethods
|
9
9
|
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
10
10
|
|
@@ -17,7 +17,7 @@ module Holidays
|
|
17
17
|
COMMON_YEAR_DAYS_IN_MONTH[month]
|
18
18
|
end
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
21
21
|
end
|
22
22
|
end
|
23
|
-
end
|
23
|
+
end
|
@@ -11,12 +11,13 @@ module Holidays
|
|
11
11
|
module Definition
|
12
12
|
module Context
|
13
13
|
class Generator
|
14
|
-
def initialize(custom_method_parser, custom_method_source_decorator, custom_methods_repository, test_parser, test_source_generator)
|
14
|
+
def initialize(custom_method_parser, custom_method_source_decorator, custom_methods_repository, test_parser, test_source_generator, module_source_generator)
|
15
15
|
@custom_method_parser = custom_method_parser
|
16
16
|
@custom_method_source_decorator = custom_method_source_decorator
|
17
17
|
@custom_methods_repository = custom_methods_repository
|
18
18
|
@test_parser = test_parser
|
19
19
|
@test_source_generator = test_source_generator
|
20
|
+
@module_source_generator = module_source_generator
|
20
21
|
end
|
21
22
|
|
22
23
|
def parse_definition_files(files)
|
@@ -66,7 +67,7 @@ module Holidays
|
|
66
67
|
custom_method_string << @custom_method_source_decorator.call(code) + ",\n\n"
|
67
68
|
end
|
68
69
|
|
69
|
-
module_src =
|
70
|
+
module_src = @module_source_generator.call(module_name, files, regions, month_strings, custom_method_string)
|
70
71
|
test_src = @test_source_generator.call(module_name, files, tests)
|
71
72
|
|
72
73
|
return module_src, test_src || ''
|
@@ -86,16 +87,27 @@ module Holidays
|
|
86
87
|
rule = {}
|
87
88
|
|
88
89
|
definition.each do |key, val|
|
90
|
+
# Ruby 2.4 doesn't have the `transform_keys` method. Once we drop 2.4 support we can
|
91
|
+
# use `val.transform_keys!(&:to_sym) if val.is_a?(Hash)` instead of this `if` statement.
|
92
|
+
if val.is_a?(Hash)
|
93
|
+
val = val.keys.each_with_object({}) do |k, result|
|
94
|
+
result[k.to_sym] = val[k]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
89
98
|
rule[key.to_sym] = val
|
90
99
|
end
|
91
100
|
|
92
|
-
rule[:
|
93
|
-
|
101
|
+
if rule[:year_ranges] && rule[:year_ranges].key?(:between)
|
102
|
+
start_year = rule[:year_ranges][:between]["start"].to_i
|
103
|
+
end_year = rule[:year_ranges][:between]["end"].to_i
|
94
104
|
|
95
|
-
|
96
|
-
rule[:year_ranges] = clean_year_ranges(rule[:year_ranges])
|
105
|
+
rule[:year_ranges][:between] = Range.new(start_year, end_year)
|
97
106
|
end
|
98
107
|
|
108
|
+
rule[:regions] = rule[:regions].collect { |r| r.to_sym }
|
109
|
+
regions << rule[:regions]
|
110
|
+
|
99
111
|
exists = false
|
100
112
|
rules_by_month[month].each do |ex|
|
101
113
|
if ex[:name] == rule[:name] and ex[:wday] == rule[:wday] and ex[:mday] == rule[:mday] and ex[:week] == rule[:week] and ex[:type] == rule[:type] and ex[:function] == rule[:function] and ex[:observed] == rule[:observed] and ex[:year_ranges] == rule[:year_ranges]
|
@@ -120,23 +132,6 @@ module Holidays
|
|
120
132
|
[regions, rules_by_month]
|
121
133
|
end
|
122
134
|
|
123
|
-
# In this case we end up parsing a range as "2006..2008" a string. This is codifying
|
124
|
-
# what we already do...today we parse as a string but when writing out to our final
|
125
|
-
# generated files it comes out as a range that Ruby interprets. This just puts it in stone
|
126
|
-
# what we want to do.
|
127
|
-
def clean_year_ranges(year_ranges)
|
128
|
-
year_ranges.collect do |year_range|
|
129
|
-
if year_range["between"]
|
130
|
-
range = year_range["between"]
|
131
|
-
if range.is_a?(String)
|
132
|
-
year_range["between"] = Range.new(*range.split("..").map(&:to_i))
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
year_range
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
135
|
#FIXME This should really be split out and tested with its own unit tests.
|
141
136
|
def generate_month_definition_strings(rules_by_month, parsed_custom_methods)
|
142
137
|
month_strings = []
|
@@ -169,19 +164,11 @@ module Holidays
|
|
169
164
|
string << ":wday => #{rule[:wday]}, :week => #{rule[:week]}, "
|
170
165
|
end
|
171
166
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
year_string << "{:#{year.keys.first} => #{year.values.first}}"
|
178
|
-
if len == index + 1
|
179
|
-
year_string << "],"
|
180
|
-
else
|
181
|
-
year_string << ","
|
182
|
-
end
|
183
|
-
end
|
184
|
-
string << year_string
|
167
|
+
if rule[:year_ranges] && rule[:year_ranges].is_a?(Hash)
|
168
|
+
selector = rule[:year_ranges].keys.first
|
169
|
+
value = rule[:year_ranges][selector]
|
170
|
+
|
171
|
+
string << ":year_ranges => { :#{selector} => #{value} },"
|
185
172
|
end
|
186
173
|
|
187
174
|
if rule[:observed]
|
@@ -216,40 +203,6 @@ module Holidays
|
|
216
203
|
method.arguments.collect { |arg| arg.to_sym }
|
217
204
|
end
|
218
205
|
end
|
219
|
-
|
220
|
-
def generate_module_src(module_name, files, regions, month_strings, custom_methods)
|
221
|
-
module_src = ""
|
222
|
-
|
223
|
-
module_src =<<-EOM
|
224
|
-
# encoding: utf-8
|
225
|
-
module Holidays
|
226
|
-
# This file is generated by the Ruby Holidays gem.
|
227
|
-
#
|
228
|
-
# Definitions loaded: #{files.join(', ')}
|
229
|
-
#
|
230
|
-
# All the definitions are available at https://github.com/holidays/holidays
|
231
|
-
module #{module_name.to_s.upcase} # :nodoc:
|
232
|
-
def self.defined_regions
|
233
|
-
[:#{regions.join(', :')}]
|
234
|
-
end
|
235
|
-
|
236
|
-
def self.holidays_by_month
|
237
|
-
{
|
238
|
-
#{month_strings.join(",\n")}
|
239
|
-
}
|
240
|
-
end
|
241
|
-
|
242
|
-
def self.custom_methods
|
243
|
-
{
|
244
|
-
#{custom_methods}
|
245
|
-
}
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
249
|
-
EOM
|
250
|
-
|
251
|
-
return module_src
|
252
|
-
end
|
253
206
|
end
|
254
207
|
end
|
255
208
|
end
|
@@ -14,7 +14,7 @@ module Holidays
|
|
14
14
|
target_region_module = Module.const_get("Holidays").const_get(region.upcase)
|
15
15
|
|
16
16
|
@definition_merger.call(
|
17
|
-
|
17
|
+
region,
|
18
18
|
target_region_module.holidays_by_month,
|
19
19
|
target_region_module.custom_methods,
|
20
20
|
)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'holidays/errors'
|
2
|
+
|
3
|
+
module Holidays
|
4
|
+
module Definition
|
5
|
+
module Generator
|
6
|
+
class Module
|
7
|
+
def call(module_name, files, regions, month_strings, custom_methods)
|
8
|
+
raise ArgumentError.new("module name cannot be nil") if module_name.nil?
|
9
|
+
raise ArgumentError.new("module name cannot be blank") if module_name.empty?
|
10
|
+
|
11
|
+
raise ArgumentError.new("files cannot be nil") if files.nil?
|
12
|
+
raise ArgumentError.new("files cannot be empty") if files.empty?
|
13
|
+
raise ArgumentError.new("files must all be strings") unless files.all? { |f| f.is_a?(String) }
|
14
|
+
|
15
|
+
raise ArgumentError.new("regions cannot be nil") if regions.nil?
|
16
|
+
raise ArgumentError.new("regions cannot be empty") if regions.empty?
|
17
|
+
|
18
|
+
raise ArgumentError.new("month strings cannot be nil") if month_strings.nil?
|
19
|
+
raise ArgumentError.new("month strings cannot be empty") if month_strings.empty?
|
20
|
+
|
21
|
+
module_src =<<-EOM
|
22
|
+
# encoding: utf-8
|
23
|
+
module Holidays
|
24
|
+
# This file is generated by the Ruby Holidays gem.
|
25
|
+
#
|
26
|
+
# Definitions loaded: #{files.join(', ')}
|
27
|
+
#
|
28
|
+
# All the definitions are available at https://github.com/holidays/holidays
|
29
|
+
module #{module_name.to_s.upcase} # :nodoc:
|
30
|
+
def self.defined_regions
|
31
|
+
[:#{regions.join(', :')}]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.holidays_by_month
|
35
|
+
{
|
36
|
+
#{month_strings.join(",\n")}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.custom_methods
|
41
|
+
{
|
42
|
+
#{custom_methods}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
EOM
|
48
|
+
|
49
|
+
module_src
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -2,6 +2,10 @@ module Holidays
|
|
2
2
|
module Definition
|
3
3
|
module Generator
|
4
4
|
class Regions
|
5
|
+
# The "ca", "mx", and "us" holiday definitions include the "northamericainformal"
|
6
|
+
# holiday definitions, but that does not make these countries subregions of one another.
|
7
|
+
NORTH_AMERICA_REGIONS = %i[ca mx us].freeze
|
8
|
+
|
5
9
|
def call(regions)
|
6
10
|
validate!(regions)
|
7
11
|
|
@@ -37,8 +41,9 @@ EOF
|
|
37
41
|
lookup = {}
|
38
42
|
|
39
43
|
regions.each do |region, subregions|
|
40
|
-
subregions.each do |
|
41
|
-
|
44
|
+
subregions.each do |subregion|
|
45
|
+
parent_region = NORTH_AMERICA_REGIONS.include?(subregion) ? subregion : region
|
46
|
+
lookup[subregion] = parent_region unless lookup.has_key?(subregion)
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
@@ -21,7 +21,7 @@ module Holidays
|
|
21
21
|
custom_methods[method_key(name, arguments)] = Entity::CustomMethod.new({
|
22
22
|
name: name,
|
23
23
|
arguments: arguments,
|
24
|
-
source: pieces["
|
24
|
+
source: pieces["ruby"],
|
25
25
|
})
|
26
26
|
end
|
27
27
|
|
@@ -36,7 +36,7 @@ module Holidays
|
|
36
36
|
{
|
37
37
|
:name => name,
|
38
38
|
:arguments => pieces["arguments"],
|
39
|
-
:source => pieces["
|
39
|
+
:source => pieces["ruby"]
|
40
40
|
}
|
41
41
|
)
|
42
42
|
end
|
@@ -8,6 +8,7 @@ module Holidays
|
|
8
8
|
|
9
9
|
def cache_between(start_date, end_date, cache_data, options)
|
10
10
|
raise ArgumentError unless cache_data
|
11
|
+
raise ArgumentError unless start_date && end_date
|
11
12
|
|
12
13
|
@cache_range[options] = start_date..end_date
|
13
14
|
@cache[options] = cache_data.group_by { |holiday| holiday[:date] }
|
@@ -15,7 +16,7 @@ module Holidays
|
|
15
16
|
|
16
17
|
def find(start_date, end_date, options)
|
17
18
|
return nil unless in_cache_range?(start_date, end_date, options)
|
18
|
-
|
19
|
+
|
19
20
|
if start_date == end_date
|
20
21
|
@cache[options].fetch(start_date, [])
|
21
22
|
else
|
@@ -41,7 +41,15 @@ module Holidays
|
|
41
41
|
private
|
42
42
|
|
43
43
|
def definition_exists?(existing_def, target_def)
|
44
|
-
existing_def[:name] == target_def[:name] &&
|
44
|
+
existing_def[:name] == target_def[:name] &&
|
45
|
+
existing_def[:wday] == target_def[:wday] &&
|
46
|
+
existing_def[:mday] == target_def[:mday] &&
|
47
|
+
existing_def[:week] == target_def[:week] &&
|
48
|
+
existing_def[:function] == target_def[:function] &&
|
49
|
+
existing_def[:function_modifier] == target_def[:function_modifier] &&
|
50
|
+
existing_def[:type] == target_def[:type] &&
|
51
|
+
existing_def[:observed] == target_def[:observed] &&
|
52
|
+
existing_def[:year_ranges] == target_def[:year_ranges]
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end
|
@@ -5,6 +5,7 @@ require 'holidays/definition/context/load'
|
|
5
5
|
require 'holidays/definition/decorator/custom_method_proc'
|
6
6
|
require 'holidays/definition/decorator/custom_method_source'
|
7
7
|
require 'holidays/definition/decorator/test'
|
8
|
+
require 'holidays/definition/generator/module'
|
8
9
|
require 'holidays/definition/generator/regions'
|
9
10
|
require 'holidays/definition/generator/test'
|
10
11
|
require 'holidays/definition/parser/custom_method'
|
@@ -29,6 +30,7 @@ module Holidays
|
|
29
30
|
custom_methods_repository,
|
30
31
|
test_parser,
|
31
32
|
test_generator,
|
33
|
+
module_generator,
|
32
34
|
)
|
33
35
|
end
|
34
36
|
|
@@ -39,6 +41,7 @@ module Holidays
|
|
39
41
|
custom_methods_repository,
|
40
42
|
test_parser,
|
41
43
|
test_generator,
|
44
|
+
module_generator,
|
42
45
|
)
|
43
46
|
end
|
44
47
|
|
@@ -115,6 +118,10 @@ module Holidays
|
|
115
118
|
)
|
116
119
|
end
|
117
120
|
|
121
|
+
def module_generator
|
122
|
+
Holidays::Definition::Generator::Module.new
|
123
|
+
end
|
124
|
+
|
118
125
|
def test_generator
|
119
126
|
Holidays::Definition::Generator::Test.new(
|
120
127
|
test_decorator,
|
@@ -14,15 +14,14 @@ module Holidays
|
|
14
14
|
regions, observed, informal = @options_parser.call(options)
|
15
15
|
dates_driver = @dates_driver_builder.call(start_date, end_date)
|
16
16
|
|
17
|
-
holidays = []
|
18
|
-
|
19
17
|
#FIXME Why are we calling the options_parser to convert the observed/informal
|
20
18
|
# symbols to bool and then...converting them back? O_o
|
21
19
|
opts = gather_options(observed, informal)
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
@definition_search
|
22
|
+
.call(dates_driver, regions, opts)
|
23
|
+
.select { |holiday| holiday[:date].between?(start_date, end_date) }
|
24
|
+
.sort_by { |a| a[:date] }
|
26
25
|
end
|
27
26
|
|
28
27
|
private
|
@@ -35,8 +34,8 @@ module Holidays
|
|
35
34
|
def gather_options(observed, informal)
|
36
35
|
opts = []
|
37
36
|
|
38
|
-
opts << :observed if observed
|
39
|
-
opts << :informal if informal
|
37
|
+
opts << :observed if observed
|
38
|
+
opts << :informal if informal
|
40
39
|
|
41
40
|
opts
|
42
41
|
end
|
@@ -11,20 +11,14 @@ module Holidays
|
|
11
11
|
def call(start_date, end_date)
|
12
12
|
dates_driver = {}
|
13
13
|
|
14
|
-
(start_date..end_date).
|
14
|
+
(start_date..end_date).each do |date|
|
15
|
+
dates_driver[date.year] = [] unless dates_driver[date.year]
|
16
|
+
dates_driver[date.year] << date.month
|
17
|
+
dates_driver = add_border_months(date, dates_driver)
|
18
|
+
end
|
15
19
|
clean(dates_driver)
|
16
20
|
end
|
17
21
|
|
18
|
-
#FIXME Why is the date_driver set to optional as the first param? That's
|
19
|
-
# just plain wrong...
|
20
|
-
def build(dates_driver = {}, date)
|
21
|
-
raise ArgumentError unless dates_driver
|
22
|
-
raise ArgumentError unless date
|
23
|
-
dates_driver[date.year] = [] unless dates_driver[date.year]
|
24
|
-
dates_driver[date.year] << date.month
|
25
|
-
dates_driver = add_border_months(date, dates_driver)
|
26
|
-
end
|
27
|
-
|
28
22
|
private
|
29
23
|
|
30
24
|
# As part of https://github.com/holidays/holidays/issues/146 I am returning
|
@@ -14,7 +14,6 @@ module Holidays
|
|
14
14
|
regions, observed, informal = @options_parser.call(options)
|
15
15
|
|
16
16
|
holidays = []
|
17
|
-
ret_holidays = []
|
18
17
|
opts = gather_options(observed, informal)
|
19
18
|
|
20
19
|
# This could be smarter but I don't have any evidence that just checking for
|
@@ -22,17 +21,18 @@ module Holidays
|
|
22
21
|
# smarter here to check in smaller increments.
|
23
22
|
dates_driver = @dates_driver_builder.call(from_date, from_date >> 12)
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
@definition_search
|
25
|
+
.call(dates_driver, regions, opts)
|
26
|
+
.sort_by { |a| a[:date] }
|
27
|
+
.each do |holiday|
|
28
|
+
if holiday[:date] >= from_date
|
29
|
+
holidays << holiday
|
30
|
+
holidays_count -= 1
|
31
|
+
break if holidays_count == 0
|
32
|
+
end
|
32
33
|
end
|
33
|
-
end
|
34
34
|
|
35
|
-
holidays.
|
35
|
+
holidays.sort_by { |a| a[:date] }
|
36
36
|
end
|
37
37
|
|
38
38
|
private
|
@@ -46,8 +46,8 @@ module Holidays
|
|
46
46
|
def gather_options(observed, informal)
|
47
47
|
opts = []
|
48
48
|
|
49
|
-
opts << :observed if observed
|
50
|
-
opts << :informal if informal
|
49
|
+
opts << :observed if observed
|
50
|
+
opts << :informal if informal
|
51
51
|
|
52
52
|
opts
|
53
53
|
end
|
@@ -42,12 +42,6 @@ module Holidays
|
|
42
42
|
|
43
43
|
loaded_regions = []
|
44
44
|
|
45
|
-
#FIXME I don't know what this means or why we have it! I'm reluctant to remove it
|
46
|
-
# at this time without understanding more. -PP 2017/3/29
|
47
|
-
#
|
48
|
-
# special case for north_america/US cross-linking
|
49
|
-
load_region!(:north_america) if regions.include?(:us)
|
50
|
-
|
51
45
|
if regions.include?(:any)
|
52
46
|
@regions_repo.all_generated.each do |r|
|
53
47
|
if @regions_repo.loaded?(r)
|