holidays 4.6.0 → 4.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/CONTRIBUTING.md +5 -5
- data/Makefile +29 -0
- data/README.md +13 -1
- data/Rakefile +2 -2
- data/definitions/au.yaml +12 -9
- data/definitions/ca.yaml +17 -2
- data/definitions/ch.yaml +1 -1
- data/definitions/index.yaml +3 -0
- data/definitions/is.yaml +1 -1
- data/definitions/jp.yaml +19 -14
- data/definitions/kr.yaml +282 -0
- data/definitions/lu.yaml +56 -0
- data/definitions/my.yaml +51 -0
- data/definitions/ups.yaml +1 -1
- data/definitions/us.yaml +1 -1
- data/lib/generated_definitions/MANIFEST +3 -0
- data/lib/generated_definitions/REGIONS.rb +1 -1
- data/lib/generated_definitions/au.rb +11 -8
- data/lib/generated_definitions/ca.rb +1 -1
- data/lib/generated_definitions/ch.rb +1 -1
- data/lib/generated_definitions/europe.rb +2 -2
- data/lib/generated_definitions/is.rb +1 -1
- data/lib/generated_definitions/jp.rb +13 -15
- data/lib/generated_definitions/kr.rb +248 -0
- data/lib/generated_definitions/lu.rb +39 -0
- data/lib/generated_definitions/my.rb +36 -0
- data/lib/generated_definitions/north_america.rb +2 -2
- data/lib/generated_definitions/scandinavia.rb +1 -1
- data/lib/generated_definitions/ups.rb +1 -1
- data/lib/generated_definitions/us.rb +1 -1
- data/lib/holidays.rb +29 -51
- data/lib/holidays/core_extensions/date.rb +1 -1
- data/lib/holidays/definition/context/function_processor.rb +86 -0
- data/lib/holidays/definition/context/generator.rb +31 -6
- data/lib/holidays/definition/parser/custom_method.rb +1 -3
- data/lib/holidays/definition/repository/holidays_by_month.rb +1 -1
- data/lib/holidays/definition/validator/region.rb +1 -3
- data/lib/holidays/errors.rb +1 -0
- data/lib/holidays/factory/date_calculator.rb +37 -0
- data/lib/holidays/factory/definition.rb +96 -0
- data/lib/holidays/factory/finder.rb +70 -0
- data/lib/holidays/finder/context/between.rb +43 -0
- data/lib/holidays/{use_case → finder}/context/dates_driver_builder.rb +6 -4
- data/lib/holidays/finder/context/next_holiday.rb +57 -0
- data/lib/holidays/{option → finder}/context/parse_options.rb +6 -8
- data/lib/holidays/finder/context/search.rb +86 -0
- data/lib/holidays/finder/context/year_holiday.rb +57 -0
- data/lib/holidays/finder/rules/in_region.rb +23 -0
- data/lib/holidays/finder/rules/year_range.rb +82 -0
- data/lib/holidays/load_all_definitions.rb +7 -5
- data/lib/holidays/version.rb +1 -1
- data/test/coverage_report.rb +7 -0
- data/test/defs/test_defs_au.rb +1 -1
- data/test/defs/test_defs_ca.rb +16 -1
- data/test/defs/test_defs_jp.rb +4 -0
- data/test/defs/test_defs_kr.rb +26 -0
- data/test/defs/test_defs_lu.rb +24 -0
- data/test/defs/test_defs_my.rb +20 -0
- data/test/defs/test_defs_north_america.rb +16 -1
- data/test/holidays/core_extensions/test_date_time.rb +7 -7
- data/test/holidays/definition/context/test_function_processor.rb +175 -0
- data/test/holidays/definition/context/test_generator.rb +18 -11
- data/test/holidays/definition/parser/test_custom_method.rb +2 -2
- data/test/holidays/definition/repository/test_proc_result_cache.rb +1 -1
- data/test/holidays/{test_date_calculator_factory.rb → factory/test_date_calculator.rb} +3 -3
- data/test/holidays/factory/test_definition.rb +53 -0
- data/test/holidays/factory/test_finder.rb +25 -0
- data/test/holidays/finder/context/test_between.rb +172 -0
- data/test/holidays/{use_case → finder}/context/test_dates_driver_builder.rb +2 -2
- data/test/holidays/finder/context/test_next_holiday.rb +156 -0
- data/test/holidays/{option → finder}/context/test_parse_options.rb +9 -9
- data/test/holidays/finder/context/test_search.rb +203 -0
- data/test/holidays/finder/context/test_year_holiday.rb +202 -0
- data/test/holidays/finder/rules/test_in_region.rb +38 -0
- data/test/holidays/finder/rules/test_year_range.rb +170 -0
- data/test/integration/README.md +9 -0
- data/test/{test_all_regions.rb → integration/test_all_regions.rb} +16 -2
- data/test/{test_custom_holidays.rb → integration/test_custom_holidays.rb} +2 -2
- data/test/{test_custom_year_range_holidays.rb → integration/test_custom_year_range_holidays.rb} +1 -1
- data/test/{test_holidays.rb → integration/test_holidays.rb} +43 -32
- data/test/{test_holidays_between.rb → integration/test_holidays_between.rb} +8 -16
- data/test/{test_multiple_regions.rb → integration/test_multiple_regions.rb} +1 -1
- data/test/test_helper.rb +3 -4
- metadata +67 -39
- data/benchmark.rb +0 -8
- data/lib/holidays/date_calculator_factory.rb +0 -35
- data/lib/holidays/definition_factory.rb +0 -86
- data/lib/holidays/option_factory.rb +0 -15
- data/lib/holidays/use_case/context/between.rb +0 -45
- data/lib/holidays/use_case/context/context_common.rb +0 -123
- data/lib/holidays/use_case/context/next_holiday.rb +0 -54
- data/lib/holidays/use_case/context/year_holiday.rb +0 -51
- data/lib/holidays/use_case_factory.rb +0 -41
- data/test/holidays/test_definition_factory.rb +0 -49
- data/test/holidays/test_option_factory.rb +0 -9
- data/test/holidays/test_use_case_factory.rb +0 -13
- data/test/holidays/use_case/context/test_between.rb +0 -77
@@ -30,11 +30,9 @@ module Holidays
|
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
attr_reader :validator
|
34
|
-
|
35
33
|
def validate!(methods)
|
36
34
|
raise ArgumentError unless methods.all? do |name, pieces|
|
37
|
-
validator.valid?(
|
35
|
+
@validator.valid?(
|
38
36
|
{
|
39
37
|
:name => name,
|
40
38
|
:arguments => pieces["arguments"],
|
@@ -12,14 +12,12 @@ module Holidays
|
|
12
12
|
region = find_wildcard_base(r)
|
13
13
|
|
14
14
|
(region == :any ||
|
15
|
-
regions_repo.exists?(region) ||
|
15
|
+
@regions_repo.exists?(region) ||
|
16
16
|
region_in_static_definitions?(region))
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
attr_reader :regions_repo
|
22
|
-
|
23
21
|
# Ex: :gb_ transformed to :gb
|
24
22
|
def find_wildcard_base(region)
|
25
23
|
r = region.to_s
|
data/lib/holidays/errors.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'holidays/date_calculator/easter'
|
2
|
+
require 'holidays/date_calculator/weekend_modifier'
|
3
|
+
require 'holidays/date_calculator/day_of_month'
|
4
|
+
|
5
|
+
module Holidays
|
6
|
+
module Factory
|
7
|
+
module DateCalculator
|
8
|
+
module Easter
|
9
|
+
module Gregorian
|
10
|
+
class << self
|
11
|
+
def easter_calculator
|
12
|
+
Holidays::DateCalculator::Easter::Gregorian.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Julian
|
18
|
+
class << self
|
19
|
+
def easter_calculator
|
20
|
+
Holidays::DateCalculator::Easter::Julian.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def weekend_modifier
|
28
|
+
Holidays::DateCalculator::WeekendModifier.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def day_of_month_calculator
|
32
|
+
Holidays::DateCalculator::DayOfMonth.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'holidays/definition/context/generator'
|
2
|
+
require 'holidays/definition/context/merger'
|
3
|
+
require 'holidays/definition/context/function_processor'
|
4
|
+
require 'holidays/definition/decorator/custom_method_proc'
|
5
|
+
require 'holidays/definition/decorator/custom_method_source'
|
6
|
+
require 'holidays/definition/parser/custom_method'
|
7
|
+
require 'holidays/definition/repository/holidays_by_month'
|
8
|
+
require 'holidays/definition/repository/regions'
|
9
|
+
require 'holidays/definition/repository/cache'
|
10
|
+
require 'holidays/definition/repository/proc_result_cache'
|
11
|
+
require 'holidays/definition/repository/custom_methods'
|
12
|
+
require 'holidays/definition/validator/custom_method'
|
13
|
+
require 'holidays/definition/validator/region'
|
14
|
+
|
15
|
+
module Holidays
|
16
|
+
module Factory
|
17
|
+
module Definition
|
18
|
+
class << self
|
19
|
+
def file_parser
|
20
|
+
Holidays::Definition::Context::Generator.new(
|
21
|
+
custom_method_parser,
|
22
|
+
custom_method_source_decorator,
|
23
|
+
custom_methods_repository,
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def source_generator
|
28
|
+
Holidays::Definition::Context::Generator.new(
|
29
|
+
custom_method_parser,
|
30
|
+
custom_method_source_decorator,
|
31
|
+
custom_methods_repository,
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def function_processor
|
36
|
+
Holidays::Definition::Context::FunctionProcessor.new(
|
37
|
+
custom_methods_repository,
|
38
|
+
proc_result_cache_repository,
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def merger
|
43
|
+
Holidays::Definition::Context::Merger.new(
|
44
|
+
holidays_by_month_repository,
|
45
|
+
regions_repository,
|
46
|
+
custom_methods_repository,
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def custom_method_parser
|
51
|
+
Holidays::Definition::Parser::CustomMethod.new(
|
52
|
+
custom_method_validator,
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def custom_method_proc_decorator
|
57
|
+
Holidays::Definition::Decorator::CustomMethodProc.new
|
58
|
+
end
|
59
|
+
|
60
|
+
def custom_method_source_decorator
|
61
|
+
Holidays::Definition::Decorator::CustomMethodSource.new
|
62
|
+
end
|
63
|
+
|
64
|
+
def region_validator
|
65
|
+
Holidays::Definition::Validator::Region.new(
|
66
|
+
regions_repository
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def custom_method_validator
|
71
|
+
Holidays::Definition::Validator::CustomMethod.new
|
72
|
+
end
|
73
|
+
|
74
|
+
def holidays_by_month_repository
|
75
|
+
@holidays_repo ||= Holidays::Definition::Repository::HolidaysByMonth.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def regions_repository
|
79
|
+
@regions_repo ||= Holidays::Definition::Repository::Regions.new
|
80
|
+
end
|
81
|
+
|
82
|
+
def cache_repository
|
83
|
+
@cache_repo ||= Holidays::Definition::Repository::Cache.new
|
84
|
+
end
|
85
|
+
|
86
|
+
def proc_result_cache_repository
|
87
|
+
@proc_result_cache_repo ||= Holidays::Definition::Repository::ProcResultCache.new
|
88
|
+
end
|
89
|
+
|
90
|
+
def custom_methods_repository
|
91
|
+
@custom_methods_repository ||= Holidays::Definition::Repository::CustomMethods.new
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'holidays/finder/context/between'
|
2
|
+
require 'holidays/finder/context/dates_driver_builder'
|
3
|
+
require 'holidays/finder/context/next_holiday'
|
4
|
+
require 'holidays/finder/context/parse_options'
|
5
|
+
require 'holidays/finder/context/search'
|
6
|
+
require 'holidays/finder/context/year_holiday'
|
7
|
+
require 'holidays/finder/rules/in_region'
|
8
|
+
require 'holidays/finder/rules/year_range'
|
9
|
+
|
10
|
+
module Holidays
|
11
|
+
module Factory
|
12
|
+
module Finder
|
13
|
+
class << self
|
14
|
+
def search
|
15
|
+
Holidays::Finder::Context::Search.new(
|
16
|
+
Factory::Definition.holidays_by_month_repository,
|
17
|
+
Factory::Definition.function_processor,
|
18
|
+
Factory::DateCalculator.day_of_month_calculator,
|
19
|
+
rules,
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def between
|
24
|
+
Holidays::Finder::Context::Between.new(
|
25
|
+
search,
|
26
|
+
dates_driver_builder,
|
27
|
+
parse_options,
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def next_holiday
|
32
|
+
Holidays::Finder::Context::NextHoliday.new(
|
33
|
+
search,
|
34
|
+
dates_driver_builder,
|
35
|
+
parse_options,
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def year_holiday
|
40
|
+
Holidays::Finder::Context::YearHoliday.new(
|
41
|
+
search,
|
42
|
+
dates_driver_builder,
|
43
|
+
parse_options,
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_options
|
48
|
+
Holidays::Finder::Context::ParseOptions.new(
|
49
|
+
Factory::Definition.regions_repository,
|
50
|
+
Factory::Definition.region_validator,
|
51
|
+
Factory::Definition.merger,
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def dates_driver_builder
|
58
|
+
Holidays::Finder::Context::DatesDriverBuilder.new
|
59
|
+
end
|
60
|
+
|
61
|
+
def rules
|
62
|
+
{
|
63
|
+
:in_region => Holidays::Finder::Rules::InRegion,
|
64
|
+
:year_range => Holidays::Finder::Rules::YearRange,
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Holidays
|
2
|
+
module Finder
|
3
|
+
module Context
|
4
|
+
class Between
|
5
|
+
def initialize(definition_search, dates_driver_builder, options_parser)
|
6
|
+
@definition_search = definition_search
|
7
|
+
@dates_driver_builder = dates_driver_builder
|
8
|
+
@options_parser = options_parser
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(start_date, end_date, options)
|
12
|
+
validate!(start_date, end_date)
|
13
|
+
|
14
|
+
regions, observed, informal = @options_parser.call(options)
|
15
|
+
dates_driver = @dates_driver_builder.call(start_date, end_date)
|
16
|
+
|
17
|
+
holidays = []
|
18
|
+
opts = gather_options(observed, informal)
|
19
|
+
|
20
|
+
holidays = @definition_search.call(dates_driver, regions, opts)
|
21
|
+
holidays = holidays.select{|holiday|holiday[:date].between?(start_date, end_date)}
|
22
|
+
holidays.sort{|a, b| a[:date] <=> b[:date] }
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def validate!(start_date, end_date)
|
28
|
+
raise ArgumentError unless start_date
|
29
|
+
raise ArgumentError unless end_date
|
30
|
+
end
|
31
|
+
|
32
|
+
def gather_options(observed, informal)
|
33
|
+
opts = []
|
34
|
+
|
35
|
+
opts << :observed if observed == true
|
36
|
+
opts << :informal if informal == true
|
37
|
+
|
38
|
+
opts
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
# we will iterate over each year and then over each month internally and check to see if the
|
3
3
|
# supplied dates match any holidays for the region and date. So if we supply start_date of 2015/1/1
|
4
4
|
# and end_date of 2015/6/1 then we will return a date driver of {:2015 => [0, 1, 2, 5, 6, 7]}.
|
5
|
-
# In the
|
6
|
-
# months to the supplied range to determine whether they should be returned to the user.
|
5
|
+
# In the logic in the various other 'finder' contexts we will iterate over this and compare dates
|
6
|
+
# in these months to the supplied range to determine whether they should be returned to the user.
|
7
7
|
module Holidays
|
8
|
-
module
|
8
|
+
module Finder
|
9
9
|
module Context
|
10
10
|
class DatesDriverBuilder
|
11
11
|
def call(start_date, end_date)
|
@@ -54,7 +54,9 @@ module Holidays
|
|
54
54
|
|
55
55
|
def clean(dates_driver)
|
56
56
|
dates_driver.each do |year, months|
|
57
|
-
|
57
|
+
# Always add variable month '0' for proc calc purposes. For example, 'easter' lives in
|
58
|
+
# 'month 0' but is vital to calculating a lot of easter-related dates.
|
59
|
+
dates_driver[year] << 0
|
58
60
|
|
59
61
|
dates_driver[year].uniq!
|
60
62
|
dates_driver[year].sort!
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Holidays
|
2
|
+
module Finder
|
3
|
+
module Context
|
4
|
+
class NextHoliday
|
5
|
+
def initialize(definition_search, dates_driver_builder, options_parser)
|
6
|
+
@definition_search = definition_search
|
7
|
+
@dates_driver_builder = dates_driver_builder
|
8
|
+
@options_parser = options_parser
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(holidays_count, from_date, options)
|
12
|
+
validate!(holidays_count, from_date)
|
13
|
+
|
14
|
+
regions, observed, informal = @options_parser.call(options)
|
15
|
+
|
16
|
+
holidays = []
|
17
|
+
ret_holidays = []
|
18
|
+
opts = gather_options(observed, informal)
|
19
|
+
|
20
|
+
# This could be smarter but I don't have any evidence that just checking for
|
21
|
+
# the next 12 months will cause us issues. If it does we can implement something
|
22
|
+
# smarter here to check in smaller increments.
|
23
|
+
dates_driver = @dates_driver_builder.call(from_date, from_date >> 12)
|
24
|
+
|
25
|
+
ret_holidays = @definition_search.call(dates_driver, regions, opts)
|
26
|
+
|
27
|
+
ret_holidays.sort{|a, b| a[:date] <=> b[:date] }.each do |holiday|
|
28
|
+
if holiday[:date] >= from_date
|
29
|
+
holidays << holiday
|
30
|
+
holidays_count -= 1
|
31
|
+
break if holidays_count == 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
holidays.sort{|a, b| a[:date] <=> b[:date] }
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def validate!(holidays_count, from_date)
|
41
|
+
raise ArgumentError unless holidays_count
|
42
|
+
raise ArgumentError if holidays_count <= 0
|
43
|
+
raise ArgumentError unless from_date
|
44
|
+
end
|
45
|
+
|
46
|
+
def gather_options(observed, informal)
|
47
|
+
opts = []
|
48
|
+
|
49
|
+
opts << :observed if observed == true
|
50
|
+
opts << :informal if informal == true
|
51
|
+
|
52
|
+
opts
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Holidays
|
2
|
-
module
|
2
|
+
module Finder
|
3
3
|
module Context
|
4
4
|
class ParseOptions
|
5
5
|
def initialize(regions_repo, region_validator, definition_merger)
|
@@ -24,8 +24,6 @@ module Holidays
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
-
attr_reader :regions_repo, :region_validator, :definition_merger
|
28
|
-
|
29
27
|
# Check regions against list of supported regions and return an array of
|
30
28
|
# symbols.
|
31
29
|
#
|
@@ -43,7 +41,7 @@ module Holidays
|
|
43
41
|
regions.delete_if do |r|
|
44
42
|
if r.to_s =~ /_$/
|
45
43
|
load_containing_region(r.to_s)
|
46
|
-
regions << regions_repo.search(r.to_s)
|
44
|
+
regions << @regions_repo.search(r.to_s)
|
47
45
|
true
|
48
46
|
end
|
49
47
|
end
|
@@ -53,7 +51,7 @@ module Holidays
|
|
53
51
|
load_definition_data("north_america") if regions.include?(:us) # special case for north_america/US cross-linking
|
54
52
|
|
55
53
|
regions.each do |region|
|
56
|
-
unless region == :any || regions_repo.exists?(region)
|
54
|
+
unless region == :any || @regions_repo.exists?(region)
|
57
55
|
begin
|
58
56
|
load_definition_data(region.to_s)
|
59
57
|
rescue NameError => e
|
@@ -73,7 +71,7 @@ module Holidays
|
|
73
71
|
|
74
72
|
def validate!(regions)
|
75
73
|
regions.each do |r|
|
76
|
-
raise UnknownRegionError unless region_validator.valid?(r)
|
74
|
+
raise UnknownRegionError unless @region_validator.valid?(r)
|
77
75
|
end
|
78
76
|
end
|
79
77
|
|
@@ -82,7 +80,7 @@ module Holidays
|
|
82
80
|
def load_containing_region(sub_reg)
|
83
81
|
prefix = sub_reg.split('_').first
|
84
82
|
|
85
|
-
return if regions_repo.exists?(prefix.to_sym)
|
83
|
+
return if @regions_repo.exists?(prefix.to_sym)
|
86
84
|
|
87
85
|
begin
|
88
86
|
load_definition_data(prefix)
|
@@ -94,7 +92,7 @@ module Holidays
|
|
94
92
|
def load_definition_data(region)
|
95
93
|
target_region_module = Module.const_get("Holidays").const_get(region.upcase)
|
96
94
|
|
97
|
-
definition_merger.call(
|
95
|
+
@definition_merger.call(
|
98
96
|
target_region_module.defined_regions,
|
99
97
|
target_region_module.holidays_by_month,
|
100
98
|
target_region_module.custom_methods,
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Holidays
|
2
|
+
module Finder
|
3
|
+
module Context
|
4
|
+
class Search
|
5
|
+
def initialize(holidays_by_month_repo, custom_method_processor, day_of_month_calculator, rules)
|
6
|
+
@holidays_by_month_repo = holidays_by_month_repo
|
7
|
+
@custom_method_processor = custom_method_processor
|
8
|
+
@day_of_month_calculator = day_of_month_calculator
|
9
|
+
@rules = rules
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(dates_driver, regions, options)
|
13
|
+
validate!(dates_driver)
|
14
|
+
|
15
|
+
holidays = []
|
16
|
+
dates_driver.each do |year, months|
|
17
|
+
months.each do |month|
|
18
|
+
next unless hbm = @holidays_by_month_repo.find_by_month(month)
|
19
|
+
hbm.each do |h|
|
20
|
+
next if (h[:type] == :informal) && !informal_set?(options)
|
21
|
+
next unless @rules[:in_region].call(regions, h[:regions])
|
22
|
+
|
23
|
+
if h[:year_ranges]
|
24
|
+
next unless @rules[:year_range].call(year, h[:year_ranges])
|
25
|
+
end
|
26
|
+
|
27
|
+
if h[:function]
|
28
|
+
result = @custom_method_processor.call(
|
29
|
+
year, month, h[:mday],
|
30
|
+
h[:function], h[:function_arguments], h[:function_modifier],
|
31
|
+
)
|
32
|
+
|
33
|
+
#FIXME The result should always be present, see https://github.com/holidays/holidays/issues/204 for more information
|
34
|
+
if result
|
35
|
+
month = result.month
|
36
|
+
mday = result.mday
|
37
|
+
end
|
38
|
+
else
|
39
|
+
mday = h[:mday] || @day_of_month_calculator.call(year, month, h[:week], h[:wday])
|
40
|
+
end
|
41
|
+
|
42
|
+
# Silently skip bad mdays
|
43
|
+
#TODO Should we be doing something different here? We have no concept of logging right now. Maybe we should add it?
|
44
|
+
begin
|
45
|
+
date = Date.civil(year, month, mday)
|
46
|
+
rescue; next; end
|
47
|
+
|
48
|
+
if observed_set?(options) && h[:observed]
|
49
|
+
date = @custom_method_processor.call(
|
50
|
+
date.year, date.month, date.day,
|
51
|
+
h[:observed],
|
52
|
+
[:date],
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
holidays << {:date => date, :name => h[:name], :regions => h[:regions]}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
holidays
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def validate!(dates_driver)
|
67
|
+
raise ArgumentError if dates_driver.nil? || dates_driver.empty?
|
68
|
+
|
69
|
+
dates_driver.each do |year, months|
|
70
|
+
months.each do |month|
|
71
|
+
raise ArgumentError unless month >= 0 && month <= 12
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def informal_set?(options)
|
77
|
+
options && options.include?(:informal) == true
|
78
|
+
end
|
79
|
+
|
80
|
+
def observed_set?(options)
|
81
|
+
options && options.include?(:observed) == true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|