holidays 4.6.0 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|