revised_holidays 9.0.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 +7 -0
- data/.github/workflows/ruby.yml +25 -0
- data/CHANGELOG.md +446 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/Makefile +45 -0
- data/README.md +337 -0
- data/Rakefile +109 -0
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/definitions/.github/workflows/ruby.yml +25 -0
- data/definitions/.gitignore +5 -0
- data/definitions/CHANGELOG.md +352 -0
- data/definitions/Gemfile +6 -0
- data/definitions/LICENSE +21 -0
- data/definitions/METHODS.yml +26 -0
- data/definitions/Makefile +9 -0
- data/definitions/README.md +22 -0
- data/definitions/ar.yaml +268 -0
- data/definitions/at.yaml +116 -0
- data/definitions/au.yaml +907 -0
- data/definitions/be_fr.yaml +153 -0
- data/definitions/be_nl.yaml +153 -0
- data/definitions/bg.yaml +186 -0
- data/definitions/br.yaml +178 -0
- data/definitions/ca.yaml +969 -0
- data/definitions/ch.yaml +277 -0
- data/definitions/cl.yaml +294 -0
- data/definitions/co.yaml +437 -0
- data/definitions/cr.yaml +100 -0
- data/definitions/cz.yaml +137 -0
- data/definitions/de.yaml +401 -0
- data/definitions/dk.yaml +220 -0
- data/definitions/doc/CONTRIBUTING.md +44 -0
- data/definitions/doc/MAINTAINERS.md +39 -0
- data/definitions/doc/SYNTAX.md +435 -0
- data/definitions/doc/architecture/README.md +15 -0
- data/definitions/doc/architecture/adr-001.md +86 -0
- data/definitions/doc/architecture/adr-002.md +64 -0
- data/definitions/ecbtarget.yaml +74 -0
- data/definitions/ee.yaml +123 -0
- data/definitions/es.yaml +495 -0
- data/definitions/federalreserve.yaml +389 -0
- data/definitions/federalreservebanks.yaml +821 -0
- data/definitions/fedex.yaml +102 -0
- data/definitions/fi.yaml +234 -0
- data/definitions/fr.yaml +157 -0
- data/definitions/gb.yaml +565 -0
- data/definitions/ge.yaml +158 -0
- data/definitions/gr.yaml +158 -0
- data/definitions/hk.yaml +287 -0
- data/definitions/hr.yaml +171 -0
- data/definitions/hu.yaml +156 -0
- data/definitions/ie.yaml +172 -0
- data/definitions/index.yaml +80 -0
- data/definitions/is.yaml +247 -0
- data/definitions/it.yaml +246 -0
- data/definitions/jp.yaml +761 -0
- data/definitions/ke.yaml +107 -0
- data/definitions/kr.yaml +166 -0
- data/definitions/kz.yaml +128 -0
- data/definitions/li.yaml +154 -0
- data/definitions/lib/validation/custom_method_validator.rb +38 -0
- data/definitions/lib/validation/definition_validator.rb +35 -0
- data/definitions/lib/validation/error.rb +11 -0
- data/definitions/lib/validation/month_validator.rb +58 -0
- data/definitions/lib/validation/run.rb +66 -0
- data/definitions/lib/validation/test_validator.rb +83 -0
- data/definitions/lt.yaml +198 -0
- data/definitions/lu.yaml +123 -0
- data/definitions/lv.yaml +229 -0
- data/definitions/ma.yaml +96 -0
- data/definitions/mt_en.yaml +131 -0
- data/definitions/mt_mt.yaml +131 -0
- data/definitions/mx.yaml +160 -0
- data/definitions/my.yaml +79 -0
- data/definitions/nerc.yaml +94 -0
- data/definitions/ng.yaml +97 -0
- data/definitions/nl.yaml +127 -0
- data/definitions/no.yaml +169 -0
- data/definitions/northamericainformal.yaml +105 -0
- data/definitions/nyse.yaml +137 -0
- data/definitions/nz.yaml +346 -0
- data/definitions/pe.yaml +208 -0
- data/definitions/ph.yaml +130 -0
- data/definitions/pl.yaml +796 -0
- data/definitions/pt.yaml +187 -0
- data/definitions/ro.yaml +240 -0
- data/definitions/rs_cyrl.yaml +129 -0
- data/definitions/rs_la.yaml +129 -0
- data/definitions/ru.yaml +108 -0
- data/definitions/se.yaml +238 -0
- data/definitions/sg.yaml +89 -0
- data/definitions/si.yaml +162 -0
- data/definitions/sk.yaml +154 -0
- data/definitions/spec/coverage_report.rb +7 -0
- data/definitions/spec/data/invalid/months/malformed/bad.yaml +15 -0
- data/definitions/spec/data/invalid/months/missing/no_months.yaml +9 -0
- data/definitions/spec/data/valid/simple.yaml +15 -0
- data/definitions/spec/spec_helper.rb +7 -0
- data/definitions/spec/validation/custom_method_validator_spec.rb +60 -0
- data/definitions/spec/validation/definition_validator_spec.rb +43 -0
- data/definitions/spec/validation/month_validator_spec.rb +175 -0
- data/definitions/spec/validation/test_validator_spec.rb +169 -0
- data/definitions/th.yaml +111 -0
- data/definitions/tn.yaml +83 -0
- data/definitions/tr.yaml +174 -0
- data/definitions/ua.yaml +161 -0
- data/definitions/unitednations.yaml +189 -0
- data/definitions/ups.yaml +102 -0
- data/definitions/us.yaml +965 -0
- data/definitions/ve.yaml +118 -0
- data/definitions/vi.yaml +54 -0
- data/definitions/za.yaml +139 -0
- data/doc/CONTRIBUTING.md +72 -0
- data/doc/MAINTAINERS.md +81 -0
- data/doc/REFERENCES +19 -0
- data/lib/generated_definitions/MANIFEST +83 -0
- data/lib/generated_definitions/REGIONS.rb +6 -0
- data/lib/generated_definitions/ar.rb +60 -0
- data/lib/generated_definitions/at.rb +37 -0
- data/lib/generated_definitions/au.rb +177 -0
- data/lib/generated_definitions/be.rb +42 -0
- data/lib/generated_definitions/be_fr.rb +36 -0
- data/lib/generated_definitions/be_nl.rb +36 -0
- data/lib/generated_definitions/bg.rb +53 -0
- data/lib/generated_definitions/br.rb +37 -0
- data/lib/generated_definitions/ca.rb +88 -0
- data/lib/generated_definitions/ch.rb +95 -0
- data/lib/generated_definitions/cl.rb +71 -0
- data/lib/generated_definitions/co.rb +121 -0
- data/lib/generated_definitions/cr.rb +35 -0
- data/lib/generated_definitions/cz.rb +37 -0
- data/lib/generated_definitions/de.rb +65 -0
- data/lib/generated_definitions/dk.rb +48 -0
- data/lib/generated_definitions/ecbtarget.rb +30 -0
- data/lib/generated_definitions/ee.rb +36 -0
- data/lib/generated_definitions/el.rb +38 -0
- data/lib/generated_definitions/es.rb +56 -0
- data/lib/generated_definitions/europe.rb +638 -0
- data/lib/generated_definitions/federalreserve.rb +35 -0
- data/lib/generated_definitions/federalreservebanks.rb +35 -0
- data/lib/generated_definitions/fedex.rb +36 -0
- data/lib/generated_definitions/fi.rb +61 -0
- data/lib/generated_definitions/fr.rb +39 -0
- data/lib/generated_definitions/gb.rb +51 -0
- data/lib/generated_definitions/ge.rb +41 -0
- data/lib/generated_definitions/gr.rb +38 -0
- data/lib/generated_definitions/hk.rb +106 -0
- data/lib/generated_definitions/hr.rb +40 -0
- data/lib/generated_definitions/hu.rb +35 -0
- data/lib/generated_definitions/ie.rb +33 -0
- data/lib/generated_definitions/is.rb +60 -0
- data/lib/generated_definitions/it.rb +45 -0
- data/lib/generated_definitions/jp.rb +166 -0
- data/lib/generated_definitions/ke.rb +34 -0
- data/lib/generated_definitions/kr.rb +40 -0
- data/lib/generated_definitions/kz.rb +38 -0
- data/lib/generated_definitions/li.rb +44 -0
- data/lib/generated_definitions/lt.rb +38 -0
- data/lib/generated_definitions/lu.rb +35 -0
- data/lib/generated_definitions/lv.rb +56 -0
- data/lib/generated_definitions/ma.rb +33 -0
- data/lib/generated_definitions/mt_en.rb +38 -0
- data/lib/generated_definitions/mt_mt.rb +38 -0
- data/lib/generated_definitions/mx.rb +54 -0
- data/lib/generated_definitions/my.rb +30 -0
- data/lib/generated_definitions/nerc.rb +30 -0
- data/lib/generated_definitions/ng.rb +33 -0
- data/lib/generated_definitions/nl.rb +37 -0
- data/lib/generated_definitions/no.rb +40 -0
- data/lib/generated_definitions/northamerica.rb +229 -0
- data/lib/generated_definitions/nyse.rb +34 -0
- data/lib/generated_definitions/nz.rb +105 -0
- data/lib/generated_definitions/pe.rb +43 -0
- data/lib/generated_definitions/ph.rb +50 -0
- data/lib/generated_definitions/pl.rb +73 -0
- data/lib/generated_definitions/pt.rb +40 -0
- data/lib/generated_definitions/ro.rb +39 -0
- data/lib/generated_definitions/rs_cyrl.rb +39 -0
- data/lib/generated_definitions/rs_la.rb +39 -0
- data/lib/generated_definitions/ru.rb +37 -0
- data/lib/generated_definitions/scandinavia.rb +166 -0
- data/lib/generated_definitions/se.rb +53 -0
- data/lib/generated_definitions/sg.rb +31 -0
- data/lib/generated_definitions/si.rb +39 -0
- data/lib/generated_definitions/sk.rb +39 -0
- data/lib/generated_definitions/southamerica.rb +248 -0
- data/lib/generated_definitions/th.rb +36 -0
- data/lib/generated_definitions/tn.rb +32 -0
- data/lib/generated_definitions/tr.rb +64 -0
- data/lib/generated_definitions/ua.rb +37 -0
- data/lib/generated_definitions/unitednations.rb +81 -0
- data/lib/generated_definitions/ups.rb +36 -0
- data/lib/generated_definitions/us.rb +153 -0
- data/lib/generated_definitions/ve.rb +36 -0
- data/lib/generated_definitions/vi.rb +29 -0
- data/lib/generated_definitions/za.rb +36 -0
- data/lib/holidays/core_extensions/date.rb +57 -0
- data/lib/holidays/core_extensions/time.rb +23 -0
- data/lib/holidays/date_calculator/day_of_month.rb +68 -0
- data/lib/holidays/date_calculator/easter.rb +91 -0
- data/lib/holidays/date_calculator/lunar_date.rb +371 -0
- data/lib/holidays/date_calculator/weekend_modifier.rb +80 -0
- data/lib/holidays/definition/context/function_processor.rb +91 -0
- data/lib/holidays/definition/context/generator.rb +209 -0
- data/lib/holidays/definition/context/load.rb +29 -0
- data/lib/holidays/definition/context/merger.rb +22 -0
- data/lib/holidays/definition/decorator/custom_method_proc.rb +28 -0
- data/lib/holidays/definition/decorator/custom_method_source.rb +30 -0
- data/lib/holidays/definition/decorator/test.rb +37 -0
- data/lib/holidays/definition/entity/custom_method.rb +11 -0
- data/lib/holidays/definition/entity/test.rb +11 -0
- data/lib/holidays/definition/generator/module.rb +54 -0
- data/lib/holidays/definition/generator/regions.rb +55 -0
- data/lib/holidays/definition/generator/test.rb +51 -0
- data/lib/holidays/definition/parser/custom_method.rb +67 -0
- data/lib/holidays/definition/parser/test.rb +86 -0
- data/lib/holidays/definition/repository/cache.rb +47 -0
- data/lib/holidays/definition/repository/custom_methods.rb +27 -0
- data/lib/holidays/definition/repository/holidays_by_month.rb +57 -0
- data/lib/holidays/definition/repository/proc_result_cache.rb +51 -0
- data/lib/holidays/definition/repository/regions.rb +46 -0
- data/lib/holidays/definition/validator/custom_method.rb +31 -0
- data/lib/holidays/definition/validator/region.rb +36 -0
- data/lib/holidays/definition/validator/test.rb +71 -0
- data/lib/holidays/errors.rb +11 -0
- data/lib/holidays/factory/date_calculator.rb +42 -0
- data/lib/holidays/factory/definition.rb +143 -0
- data/lib/holidays/factory/finder.rb +70 -0
- data/lib/holidays/finder/context/between.rb +45 -0
- data/lib/holidays/finder/context/dates_driver_builder.rb +64 -0
- data/lib/holidays/finder/context/next_holiday.rb +57 -0
- data/lib/holidays/finder/context/parse_options.rb +104 -0
- data/lib/holidays/finder/context/search.rb +111 -0
- data/lib/holidays/finder/context/year_holiday.rb +57 -0
- data/lib/holidays/finder/rules/in_region.rb +31 -0
- data/lib/holidays/finder/rules/year_range.rb +58 -0
- data/lib/holidays/load_all_definitions.rb +56 -0
- data/lib/holidays/version.rb +3 -0
- data/lib/holidays.rb +130 -0
- data/lib/revised_holidays.rb +1 -0
- data/revised_holidays.gemspec +31 -0
- data/test/coverage_report.rb +26 -0
- data/test/data/test_custom_govt_holiday_defs.yaml +5 -0
- data/test/data/test_custom_informal_holidays_defs.yaml +11 -0
- data/test/data/test_custom_year_range_holiday_defs.yaml +31 -0
- data/test/data/test_invalid_region.rb +15 -0
- data/test/data/test_multiple_custom_holiday_defs.yaml +12 -0
- 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/data/test_region.rb +15 -0
- data/test/data/test_single_custom_holiday_defs.yaml +12 -0
- data/test/data/test_single_custom_holiday_with_custom_procs.yaml +28 -0
- data/test/defs/test_defs_ar.rb +69 -0
- data/test/defs/test_defs_at.rb +31 -0
- data/test/defs/test_defs_au.rb +233 -0
- data/test/defs/test_defs_be_fr.rb +45 -0
- data/test/defs/test_defs_be_nl.rb +45 -0
- data/test/defs/test_defs_bg.rb +41 -0
- data/test/defs/test_defs_br.rb +49 -0
- data/test/defs/test_defs_ca.rb +289 -0
- data/test/defs/test_defs_ch.rb +51 -0
- data/test/defs/test_defs_cl.rb +69 -0
- data/test/defs/test_defs_co.rb +113 -0
- data/test/defs/test_defs_cr.rb +29 -0
- data/test/defs/test_defs_cz.rb +37 -0
- data/test/defs/test_defs_de.rb +89 -0
- data/test/defs/test_defs_dk.rb +47 -0
- data/test/defs/test_defs_ecbtarget.rb +27 -0
- data/test/defs/test_defs_ee.rb +41 -0
- data/test/defs/test_defs_es.rb +137 -0
- data/test/defs/test_defs_europe.rb +1522 -0
- data/test/defs/test_defs_fed_ex.rb +24 -0
- data/test/defs/test_defs_federalreserve.rb +119 -0
- data/test/defs/test_defs_federalreservebanks.rb +251 -0
- data/test/defs/test_defs_fedex.rb +31 -0
- data/test/defs/test_defs_fi.rb +59 -0
- data/test/defs/test_defs_fr.rb +43 -0
- data/test/defs/test_defs_gb.rb +159 -0
- data/test/defs/test_defs_ge.rb +53 -0
- data/test/defs/test_defs_gr.rb +41 -0
- data/test/defs/test_defs_hk.rb +59 -0
- data/test/defs/test_defs_hr.rb +45 -0
- data/test/defs/test_defs_hu.rb +47 -0
- data/test/defs/test_defs_ie.rb +53 -0
- data/test/defs/test_defs_is.rb +51 -0
- data/test/defs/test_defs_it.rb +55 -0
- data/test/defs/test_defs_jp.rb +159 -0
- data/test/defs/test_defs_ke.rb +31 -0
- data/test/defs/test_defs_kr.rb +37 -0
- data/test/defs/test_defs_kz.rb +39 -0
- data/test/defs/test_defs_li.rb +35 -0
- data/test/defs/test_defs_lt.rb +65 -0
- data/test/defs/test_defs_lu.rb +35 -0
- data/test/defs/test_defs_lv.rb +98 -0
- data/test/defs/test_defs_ma.rb +29 -0
- data/test/defs/test_defs_mt_en.rb +41 -0
- data/test/defs/test_defs_mt_mt.rb +41 -0
- data/test/defs/test_defs_mx.rb +49 -0
- data/test/defs/test_defs_my.rb +23 -0
- data/test/defs/test_defs_nerc.rb +29 -0
- data/test/defs/test_defs_ng.rb +29 -0
- data/test/defs/test_defs_nl.rb +33 -0
- data/test/defs/test_defs_no.rb +43 -0
- data/test/defs/test_defs_northamerica.rb +667 -0
- data/test/defs/test_defs_nyse.rb +46 -0
- data/test/defs/test_defs_nz.rb +67 -0
- data/test/defs/test_defs_pe.rb +47 -0
- data/test/defs/test_defs_ph.rb +29 -0
- data/test/defs/test_defs_pl.rb +229 -0
- data/test/defs/test_defs_pt.rb +47 -0
- data/test/defs/test_defs_ro.rb +65 -0
- data/test/defs/test_defs_rs_cyrl.rb +46 -0
- data/test/defs/test_defs_rs_la.rb +46 -0
- data/test/defs/test_defs_ru.rb +34 -0
- data/test/defs/test_defs_scandinavia.rb +215 -0
- data/test/defs/test_defs_se.rb +59 -0
- data/test/defs/test_defs_sg.rb +25 -0
- data/test/defs/test_defs_si.rb +105 -0
- data/test/defs/test_defs_sk.rb +41 -0
- data/test/defs/test_defs_southamerica.rb +327 -0
- data/test/defs/test_defs_th.rb +33 -0
- data/test/defs/test_defs_tn.rb +27 -0
- data/test/defs/test_defs_tr.rb +60 -0
- data/test/defs/test_defs_ua.rb +41 -0
- data/test/defs/test_defs_unitednations.rb +11 -0
- data/test/defs/test_defs_ups.rb +31 -0
- data/test/defs/test_defs_us.rb +387 -0
- data/test/defs/test_defs_ve.rb +35 -0
- data/test/defs/test_defs_vi.rb +22 -0
- data/test/defs/test_defs_za.rb +35 -0
- data/test/holidays/core_extensions/test_date.rb +122 -0
- data/test/holidays/core_extensions/test_date_time.rb +60 -0
- data/test/holidays/date_calculator/test_day_of_month.rb +27 -0
- data/test/holidays/date_calculator/test_easter_gregorian.rb +30 -0
- data/test/holidays/date_calculator/test_easter_julian.rb +36 -0
- data/test/holidays/date_calculator/test_lunar_date.rb +89 -0
- data/test/holidays/date_calculator/test_weekend_modifier.rb +54 -0
- data/test/holidays/definition/context/test_function_processor.rb +199 -0
- data/test/holidays/definition/context/test_generator.rb +226 -0
- data/test/holidays/definition/context/test_load.rb +37 -0
- data/test/holidays/definition/context/test_merger.rb +25 -0
- data/test/holidays/definition/decorator/test_custom_method_proc.rb +113 -0
- data/test/holidays/definition/decorator/test_custom_method_source.rb +96 -0
- data/test/holidays/definition/decorator/test_test.rb +123 -0
- data/test/holidays/definition/generator/test_module.rb +268 -0
- data/test/holidays/definition/generator/test_regions.rb +97 -0
- data/test/holidays/definition/generator/test_test.rb +113 -0
- data/test/holidays/definition/parser/test_custom_method.rb +79 -0
- data/test/holidays/definition/parser/test_test.rb +142 -0
- data/test/holidays/definition/repository/test_cache.rb +123 -0
- data/test/holidays/definition/repository/test_custom_methods.rb +43 -0
- data/test/holidays/definition/repository/test_holidays_by_month.rb +275 -0
- data/test/holidays/definition/repository/test_proc_result_cache.rb +91 -0
- data/test/holidays/definition/repository/test_regions.rb +104 -0
- data/test/holidays/definition/validator/test_custom_method.rb +94 -0
- data/test/holidays/definition/validator/test_region.rb +54 -0
- data/test/holidays/definition/validator/test_test.rb +60 -0
- data/test/holidays/finder/context/test_between.rb +172 -0
- data/test/holidays/finder/context/test_dates_driver_builder.rb +91 -0
- data/test/holidays/finder/context/test_next_holiday.rb +156 -0
- data/test/holidays/finder/context/test_parse_options.rb +141 -0
- data/test/holidays/finder/context/test_search.rb +232 -0
- data/test/holidays/finder/context/test_year_holiday.rb +202 -0
- data/test/holidays/finder/rules/test_in_region.rb +42 -0
- data/test/holidays/finder/rules/test_year_range.rb +166 -0
- data/test/integration/README.md +9 -0
- data/test/integration/test_all_regions.rb +49 -0
- data/test/integration/test_any_holidays_during_work_week.rb +90 -0
- data/test/integration/test_available_regions.rb +23 -0
- data/test/integration/test_custom_holidays.rb +41 -0
- data/test/integration/test_custom_informal_holidays.rb +15 -0
- data/test/integration/test_custom_year_range_holidays.rb +35 -0
- data/test/integration/test_holidays.rb +243 -0
- data/test/integration/test_holidays_between.rb +87 -0
- data/test/integration/test_multiple_regions.rb +71 -0
- data/test/integration/test_multiple_regions_with_conflict.rb +29 -0
- data/test/integration/test_nonstandard_regions.rb +25 -0
- data/test/test_helper.rb +37 -0
- metadata +649 -0
|
@@ -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.loader,
|
|
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,45 @@
|
|
|
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
|
+
#FIXME Why are we calling the options_parser to convert the observed/informal
|
|
18
|
+
# symbols to bool and then...converting them back? O_o
|
|
19
|
+
opts = gather_options(observed, informal)
|
|
20
|
+
|
|
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] }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def validate!(start_date, end_date)
|
|
30
|
+
raise ArgumentError unless start_date
|
|
31
|
+
raise ArgumentError unless end_date
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def gather_options(observed, informal)
|
|
35
|
+
opts = []
|
|
36
|
+
|
|
37
|
+
opts << :observed if observed
|
|
38
|
+
opts << :informal if informal
|
|
39
|
+
|
|
40
|
+
opts
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# This context builds a hash that contains {:year => [<array of months>]}. The idea is that
|
|
2
|
+
# we will iterate over each year and then over each month internally and check to see if the
|
|
3
|
+
# supplied dates match any holidays for the region and date. So if we supply start_date of 2015/1/1
|
|
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 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
|
+
module Holidays
|
|
8
|
+
module Finder
|
|
9
|
+
module Context
|
|
10
|
+
class DatesDriverBuilder
|
|
11
|
+
def call(start_date, end_date)
|
|
12
|
+
dates_driver = {}
|
|
13
|
+
|
|
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
|
|
19
|
+
clean(dates_driver)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# As part of https://github.com/holidays/holidays/issues/146 I am returning
|
|
25
|
+
# additional months in an attempt to catch month-spanning date situations (i.e.
|
|
26
|
+
# dates falling on 2/1 but being observed on 1/31). By including the additional months
|
|
27
|
+
# we are increasing runtimes slightly but improving accuracy, which is more important
|
|
28
|
+
# to me at this stage.
|
|
29
|
+
def add_border_months(current_date, dates_driver)
|
|
30
|
+
if current_date.month == 1
|
|
31
|
+
dates_driver[current_date.year] << 2
|
|
32
|
+
|
|
33
|
+
prev_year = current_date.year - 1
|
|
34
|
+
dates_driver[prev_year] = [] unless dates_driver[prev_year]
|
|
35
|
+
dates_driver[prev_year] << 12
|
|
36
|
+
elsif current_date.month == 12
|
|
37
|
+
dates_driver[current_date.year] << 11
|
|
38
|
+
|
|
39
|
+
next_year = current_date.year + 1
|
|
40
|
+
dates_driver[next_year] = [] unless dates_driver[next_year]
|
|
41
|
+
dates_driver[next_year] << 1
|
|
42
|
+
else
|
|
43
|
+
dates_driver[current_date.year] << current_date.month - 1 << current_date.month + 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
dates_driver
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def clean(dates_driver)
|
|
50
|
+
dates_driver.each do |year, months|
|
|
51
|
+
# Always add variable month '0' for proc calc purposes. For example, 'easter' lives in
|
|
52
|
+
# 'month 0' but is vital to calculating a lot of easter-related dates.
|
|
53
|
+
dates_driver[year] << 0
|
|
54
|
+
|
|
55
|
+
dates_driver[year].uniq!
|
|
56
|
+
dates_driver[year].sort!
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
dates_driver
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -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
|
+
opts = gather_options(observed, informal)
|
|
18
|
+
|
|
19
|
+
# This could be smarter but I don't have any evidence that just checking for
|
|
20
|
+
# the next 12 months will cause us issues. If it does we can implement something
|
|
21
|
+
# smarter here to check in smaller increments.
|
|
22
|
+
dates_driver = @dates_driver_builder.call(from_date, from_date >> 12)
|
|
23
|
+
|
|
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
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
holidays.sort_by { |a| a[: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
|
|
50
|
+
opts << :informal if informal
|
|
51
|
+
|
|
52
|
+
opts
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Finder
|
|
3
|
+
module Context
|
|
4
|
+
class ParseOptions
|
|
5
|
+
def initialize(regions_repo, region_validator, definition_loader)
|
|
6
|
+
@regions_repo = regions_repo
|
|
7
|
+
@region_validator = region_validator
|
|
8
|
+
@definition_loader = definition_loader
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Returns [(arr)regions, (bool)observed, (bool)informal]
|
|
12
|
+
def call(*options)
|
|
13
|
+
options.flatten!
|
|
14
|
+
|
|
15
|
+
#TODO This is garbage. These two deletes MUST come before the
|
|
16
|
+
# parse_regions call, otherwise it thinks that :observed and :informal
|
|
17
|
+
# are regions to parse. We should be splitting these things out.
|
|
18
|
+
observed = options.delete(:observed) ? true : false
|
|
19
|
+
informal = options.delete(:informal) ? true : false
|
|
20
|
+
regions = parse_regions!(options)
|
|
21
|
+
|
|
22
|
+
return regions, observed, informal
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# Check regions against list of supported regions and return an array of
|
|
28
|
+
# symbols.
|
|
29
|
+
#
|
|
30
|
+
# If a wildcard region is found (e.g. :ca_) it is expanded into all
|
|
31
|
+
# of its available sub regions.
|
|
32
|
+
def parse_regions!(regions)
|
|
33
|
+
regions = [regions] unless regions.kind_of?(Array)
|
|
34
|
+
|
|
35
|
+
if regions.empty?
|
|
36
|
+
regions = [:any]
|
|
37
|
+
else
|
|
38
|
+
regions = regions.collect { |r| r.to_sym }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
validate!(regions)
|
|
42
|
+
|
|
43
|
+
loaded_regions = []
|
|
44
|
+
|
|
45
|
+
if regions.include?(:any)
|
|
46
|
+
@regions_repo.all_generated.each do |r|
|
|
47
|
+
if @regions_repo.loaded?(r)
|
|
48
|
+
loaded_regions << r
|
|
49
|
+
next
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
target = @regions_repo.parent_region_lookup(r)
|
|
53
|
+
load_region!(target)
|
|
54
|
+
|
|
55
|
+
loaded_regions << r
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
regions.each do |r|
|
|
59
|
+
if is_wildcard?(r)
|
|
60
|
+
loaded_regions << load_wildcard_parent!(r)
|
|
61
|
+
else
|
|
62
|
+
parent = @regions_repo.parent_region_lookup(r)
|
|
63
|
+
|
|
64
|
+
target = parent || r
|
|
65
|
+
|
|
66
|
+
if @regions_repo.loaded?(target)
|
|
67
|
+
loaded_regions << r
|
|
68
|
+
next
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
load_region!(target)
|
|
72
|
+
|
|
73
|
+
loaded_regions << r
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
loaded_regions.flatten.compact.uniq
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def validate!(regions)
|
|
82
|
+
regions.each do |r|
|
|
83
|
+
raise InvalidRegion unless @region_validator.valid?(r)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def is_wildcard?(r)
|
|
88
|
+
r.to_s =~ /_$/
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def load_wildcard_parent!(wildcard_region)
|
|
92
|
+
prefix = wildcard_region.to_s.split('_').first.to_sym
|
|
93
|
+
load_region!(prefix)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def load_region!(r)
|
|
97
|
+
@definition_loader.call(r)
|
|
98
|
+
rescue NameError, LoadError => e
|
|
99
|
+
raise UnknownRegionError.new(e), "Could not load region: #{r}"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
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 informal_type?(h[:type]) && !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
|
+
date = build_date(year, month, h)
|
|
28
|
+
next unless date
|
|
29
|
+
|
|
30
|
+
if observed_set?(options) && h[:observed]
|
|
31
|
+
date = build_observed_date(date, regions, h)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
holidays << {:date => date, :name => h[:name], :regions => h[:regions]}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
holidays
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def validate!(dates_driver)
|
|
45
|
+
#FIXME This should give some kind of error message that indicates the
|
|
46
|
+
# problem.
|
|
47
|
+
raise ArgumentError if dates_driver.nil? || dates_driver.empty?
|
|
48
|
+
|
|
49
|
+
dates_driver.each do |year, months|
|
|
50
|
+
months.each do |month|
|
|
51
|
+
raise ArgumentError unless month >= 0 && month <= 12
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def informal_type?(type)
|
|
57
|
+
type && [:informal, 'informal'].include?(type)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def informal_set?(options)
|
|
61
|
+
options && options.include?(:informal) == true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def observed_set?(options)
|
|
65
|
+
options && options.include?(:observed) == true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def build_date(year, month, h)
|
|
69
|
+
if h[:function]
|
|
70
|
+
holiday = custom_holiday(year, month, h)
|
|
71
|
+
#FIXME The result should always be present, see https://github.com/holidays/holidays/issues/204 for more information
|
|
72
|
+
current_month = holiday&.month
|
|
73
|
+
current_day = holiday&.mday
|
|
74
|
+
else
|
|
75
|
+
current_month = month
|
|
76
|
+
current_day = h[:mday] || @day_of_month_calculator.call(year, month, h[:week], h[:wday])
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Silently skip bad mdays
|
|
80
|
+
#TODO Should we be doing something different here? We have no concept of logging right now. Maybe we should add it?
|
|
81
|
+
Date.civil(year, current_month, current_day) rescue nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def custom_holiday(year, month, h)
|
|
85
|
+
@custom_method_processor.call(
|
|
86
|
+
#FIXME This seems like a bug, we seem to expect the day in here in the au defs?
|
|
87
|
+
build_custom_method_input(year, month, h[:mday], h[:regions]),
|
|
88
|
+
h[:function], h[:function_arguments], h[:function_modifier],
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def build_custom_method_input(year, month, day, regions)
|
|
93
|
+
{
|
|
94
|
+
year: year,
|
|
95
|
+
month: month,
|
|
96
|
+
day: day,
|
|
97
|
+
region: regions.first, #FIXME This isn't ideal but will work for our current use case...
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def build_observed_date(date, regions, h)
|
|
102
|
+
@custom_method_processor.call(
|
|
103
|
+
build_custom_method_input(date.year, date.month, date.day, regions),
|
|
104
|
+
h[:observed],
|
|
105
|
+
[:date],
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Finder
|
|
3
|
+
module Context
|
|
4
|
+
class YearHoliday
|
|
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(from_date, options)
|
|
12
|
+
validate!(from_date)
|
|
13
|
+
|
|
14
|
+
regions, observed, informal = @options_parser.call(options)
|
|
15
|
+
|
|
16
|
+
# This could be smarter but I don't have any evidence that just checking for
|
|
17
|
+
# the next 12 months will cause us issues. If it does we can implement something
|
|
18
|
+
# smarter here to check in smaller increments.
|
|
19
|
+
#
|
|
20
|
+
#FIXME Could this be until the to_date instead? Save us some processing?
|
|
21
|
+
# This is matching what was in holidays.rb currently so I'm keeping it. -pp
|
|
22
|
+
dates_driver = @dates_driver_builder.call(from_date, from_date >> 12)
|
|
23
|
+
|
|
24
|
+
to_date = Date.civil(from_date.year, 12, 31)
|
|
25
|
+
holidays = []
|
|
26
|
+
ret_holidays = []
|
|
27
|
+
opts = gather_options(observed, informal)
|
|
28
|
+
|
|
29
|
+
ret_holidays = @definition_search.call(dates_driver, regions, opts)
|
|
30
|
+
|
|
31
|
+
ret_holidays.each do |holiday|
|
|
32
|
+
if holiday[:date] >= from_date && holiday[:date] <= to_date
|
|
33
|
+
holidays << holiday
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
holidays.sort{|a, b| a[:date] <=> b[:date] }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def validate!(from_date)
|
|
43
|
+
raise ArgumentError unless from_date && from_date.is_a?(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
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Finder
|
|
3
|
+
module Rules
|
|
4
|
+
class InRegion
|
|
5
|
+
class << self
|
|
6
|
+
def call(requested, available)
|
|
7
|
+
return true if requested.include?(:any)
|
|
8
|
+
|
|
9
|
+
# When an underscore is encountered, derive the parent regions
|
|
10
|
+
# symbol and check for both.
|
|
11
|
+
requested = requested.collect do |r|
|
|
12
|
+
if r.to_s =~ /_/
|
|
13
|
+
chunks = r.to_s.split('_')
|
|
14
|
+
|
|
15
|
+
chunks.length.downto(1).map do |num|
|
|
16
|
+
chunks[0..-num].join('_').to_sym
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
r
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
requested = requested.flatten.uniq
|
|
24
|
+
|
|
25
|
+
available.any? { |avail| requested.include?(avail) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Finder
|
|
3
|
+
module Rules
|
|
4
|
+
class YearRange
|
|
5
|
+
class << self
|
|
6
|
+
UNTIL = :until
|
|
7
|
+
FROM = :from
|
|
8
|
+
LIMITED = :limited
|
|
9
|
+
BETWEEN = :between
|
|
10
|
+
|
|
11
|
+
def call(target_year, year_range_defs)
|
|
12
|
+
validate!(target_year, year_range_defs)
|
|
13
|
+
|
|
14
|
+
operator = year_range_defs.keys.first
|
|
15
|
+
rule_value = year_range_defs[operator]
|
|
16
|
+
|
|
17
|
+
case operator
|
|
18
|
+
when UNTIL
|
|
19
|
+
matched = target_year <= rule_value
|
|
20
|
+
when FROM
|
|
21
|
+
matched = target_year >= rule_value
|
|
22
|
+
when LIMITED
|
|
23
|
+
matched = rule_value.include?(target_year)
|
|
24
|
+
when BETWEEN
|
|
25
|
+
matched = rule_value.cover?(target_year)
|
|
26
|
+
else
|
|
27
|
+
matched = false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
matched
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def validate!(target_year, year_ranges)
|
|
36
|
+
raise ArgumentError.new("target_year must be a number") unless target_year.is_a?(Integer)
|
|
37
|
+
raise ArgumentError.new("year_ranges cannot be missing") if year_ranges.nil? || year_ranges.empty?
|
|
38
|
+
raise ArgumentError.new("year_ranges must contain a hash with a single operator") unless year_ranges.is_a?(Hash) && year_ranges.size == 1
|
|
39
|
+
|
|
40
|
+
operator = year_ranges.keys.first
|
|
41
|
+
value = year_ranges[operator]
|
|
42
|
+
|
|
43
|
+
raise ArgumentError.new("Invalid operator found: '#{operator}'") unless [UNTIL, FROM, LIMITED, BETWEEN].include?(operator)
|
|
44
|
+
|
|
45
|
+
case operator
|
|
46
|
+
when UNTIL, FROM
|
|
47
|
+
raise ArgumentError.new("#{UNTIL} and #{FROM} operator value must be a number, received: '#{value}'") unless value.is_a?(Integer)
|
|
48
|
+
when LIMITED
|
|
49
|
+
raise ArgumentError.new(":limited operator value must be an array containing at least one integer value, received: '#{value}'") unless value.is_a?(Array) && value.size >= 1 && value.all? { |v| v.is_a?(Integer) }
|
|
50
|
+
when BETWEEN
|
|
51
|
+
raise ArgumentError.new(":between operator value must be a range, received: '#{value}'") unless value.is_a?(Range)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
#TODO This file should be renamed. It's no longer about definitions, really.
|
|
3
|
+
class LoadAllDefinitions
|
|
4
|
+
class << self
|
|
5
|
+
def call
|
|
6
|
+
#FIXME I need a better way to do this. I'm thinking of putting these 'common' methods
|
|
7
|
+
# into some kind of definition file so it can be loaded automatically but I'm afraid
|
|
8
|
+
# of making that big of a breaking API change since these are public. For the time
|
|
9
|
+
# being I'll load them manually like this.
|
|
10
|
+
#
|
|
11
|
+
# NOTE: These are no longer public! We can do whatever we want here!
|
|
12
|
+
global_methods = {
|
|
13
|
+
"easter(year)" => gregorian_easter.method(:calculate_easter_for).to_proc,
|
|
14
|
+
"orthodox_easter(year)" => gregorian_easter.method(:calculate_orthodox_easter_for).to_proc,
|
|
15
|
+
"orthodox_easter_julian(year)" => julian_easter.method(:calculate_orthodox_easter_for).to_proc,
|
|
16
|
+
"to_monday_if_sunday(date)" => weekend_modifier.method(:to_monday_if_sunday).to_proc,
|
|
17
|
+
"to_monday_if_weekend(date)" => weekend_modifier.method(:to_monday_if_weekend).to_proc,
|
|
18
|
+
"to_weekday_if_boxing_weekend(date)" => weekend_modifier.method(:to_weekday_if_boxing_weekend).to_proc,
|
|
19
|
+
"to_weekday_if_boxing_weekend_from_year(year)" => weekend_modifier.method(:to_weekday_if_boxing_weekend_from_year).to_proc,
|
|
20
|
+
"to_weekday_if_weekend(date)" => weekend_modifier.method(:to_weekday_if_weekend).to_proc,
|
|
21
|
+
"calculate_day_of_month(year, month, day, wday)" => day_of_month_calculator.method(:call).to_proc,
|
|
22
|
+
"to_weekday_if_boxing_weekend_from_year_or_to_tuesday_if_monday(year)" => weekend_modifier.method(:to_weekday_if_boxing_weekend_from_year_or_to_tuesday_if_monday).to_proc,
|
|
23
|
+
"to_tuesday_if_sunday_or_monday_if_saturday(date)" => weekend_modifier.method(:to_tuesday_if_sunday_or_monday_if_saturday).to_proc,
|
|
24
|
+
"lunar_to_solar(year, month, day, region)" => lunar_date.method(:to_solar).to_proc,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Factory::Definition.custom_methods_repository.add(global_methods)
|
|
28
|
+
|
|
29
|
+
static_regions_definition = "#{Holidays::DEFINITIONS_PATH}/REGIONS.rb"
|
|
30
|
+
require static_regions_definition
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def gregorian_easter
|
|
36
|
+
Factory::DateCalculator::Easter::Gregorian.easter_calculator
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def julian_easter
|
|
40
|
+
Factory::DateCalculator::Easter::Julian.easter_calculator
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def weekend_modifier
|
|
44
|
+
Factory::DateCalculator.weekend_modifier
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def day_of_month_calculator
|
|
48
|
+
Factory::DateCalculator.day_of_month_calculator
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def lunar_date
|
|
52
|
+
Factory::DateCalculator.lunar_date
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|