holidays 2.2.0 → 3.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 +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +22 -8
- data/Rakefile +26 -8
- data/bin/console +7 -0
- data/bin/setup +5 -0
- data/{data → definitions}/SYNTAX.rdoc +0 -0
- data/{data → definitions}/ar.yaml +0 -0
- data/{data → definitions}/at.yaml +1 -1
- data/{data → definitions}/au.yaml +80 -51
- data/{data → definitions}/be.yaml +0 -0
- data/{data → definitions}/br.yaml +0 -0
- data/{data → definitions}/ca.yaml +0 -0
- data/{data → definitions}/ch.yaml +0 -0
- data/{data → definitions}/cl.yaml +0 -0
- data/{data → definitions}/cr.yaml +0 -0
- data/{data → definitions}/cz.yaml +0 -0
- data/{data → definitions}/de.yaml +25 -34
- data/{data → definitions}/dk.yaml +0 -0
- data/{data → definitions}/ecb_target.yaml +2 -2
- data/{data → definitions}/el.yaml +0 -0
- data/{data → definitions}/es.yaml +37 -26
- data/{data → definitions}/federal_reserve.yaml +0 -0
- data/{data → definitions}/fedex.yaml +9 -3
- data/{data → definitions}/fi.yaml +0 -0
- data/{data → definitions}/fr.yaml +0 -0
- data/{data → definitions}/gb.yaml +19 -19
- data/{data → definitions}/hr.yaml +0 -0
- data/{data → definitions}/hu.yaml +1 -1
- data/{data → definitions}/ie.yaml +0 -0
- data/{data → definitions}/index.yaml +0 -0
- data/{data → definitions}/is.yaml +0 -0
- data/{data → definitions}/it.yaml +0 -0
- data/{data → definitions}/jp.yaml +3 -3
- data/{data → definitions}/li.yaml +3 -3
- data/{data → definitions}/lt.yaml +0 -0
- data/{data → definitions}/ma.yaml +0 -0
- data/{data → definitions}/mx.yaml +0 -0
- data/{data → definitions}/nerc.yaml +0 -0
- data/{data → definitions}/nl.yaml +0 -0
- data/{data → definitions}/no.yaml +0 -0
- data/{data → definitions}/north_america_informal.yaml +0 -0
- data/{data → definitions}/nyse.yaml +0 -0
- data/{data → definitions}/nz.yaml +21 -10
- data/{data → definitions}/ph.yaml +0 -0
- data/{data → definitions}/pl.yaml +0 -0
- data/{data → definitions}/pt.yaml +0 -0
- data/{data → definitions}/ro.yaml +1 -2
- data/{data → definitions}/se.yaml +0 -0
- data/{data → definitions}/sg.yaml +0 -0
- data/{data → definitions}/si.yaml +6 -6
- data/{data → definitions}/sk.yaml +0 -0
- data/{data → definitions}/united_nations.yaml +0 -0
- data/{data → definitions}/ups.yaml +17 -11
- data/{data → definitions}/us.yaml +20 -15
- data/{data → definitions}/ve.yaml +0 -0
- data/{data → definitions}/vi.yaml +0 -0
- data/{data → definitions}/za.yaml +0 -0
- data/holidays.gemspec +2 -1
- data/lib/generated_definitions/MANIFEST +56 -0
- data/lib/generated_definitions/REGIONS.rb +4 -0
- data/lib/{holidays → generated_definitions}/ar.rb +2 -2
- data/lib/{holidays → generated_definitions}/at.rb +2 -2
- data/lib/{holidays → generated_definitions}/au.rb +19 -10
- data/lib/{holidays → generated_definitions}/be.rb +2 -2
- data/lib/{holidays → generated_definitions}/br.rb +2 -2
- data/lib/{holidays → generated_definitions}/ca.rb +2 -2
- data/lib/{holidays → generated_definitions}/ch.rb +2 -2
- data/lib/{holidays → generated_definitions}/cl.rb +2 -2
- data/lib/{holidays → generated_definitions}/cr.rb +2 -2
- data/lib/{holidays → generated_definitions}/cz.rb +2 -2
- data/lib/{holidays → generated_definitions}/de.rb +5 -4
- data/lib/{holidays → generated_definitions}/dk.rb +2 -2
- data/lib/{holidays → generated_definitions}/ecb_target.rb +2 -2
- data/lib/{holidays → generated_definitions}/el.rb +2 -2
- data/lib/{holidays → generated_definitions}/es.rb +6 -6
- data/lib/{holidays → generated_definitions}/europe.rb +7 -6
- data/lib/{holidays → generated_definitions}/fed_ex.rb +8 -3
- data/lib/{holidays → generated_definitions}/federal_reserve.rb +2 -2
- data/lib/{holidays → generated_definitions}/fi.rb +2 -2
- data/lib/{holidays → generated_definitions}/fr.rb +2 -2
- data/lib/{holidays → generated_definitions}/gb.rb +2 -2
- data/lib/{holidays → generated_definitions}/hr.rb +2 -2
- data/lib/{holidays → generated_definitions}/hu.rb +2 -2
- data/lib/{holidays → generated_definitions}/ie.rb +2 -2
- data/lib/{holidays → generated_definitions}/is.rb +2 -2
- data/lib/{holidays → generated_definitions}/it.rb +2 -2
- data/lib/{holidays → generated_definitions}/jp.rb +5 -5
- data/lib/{holidays → generated_definitions}/li.rb +2 -2
- data/lib/{holidays → generated_definitions}/lt.rb +2 -2
- data/lib/{holidays → generated_definitions}/ma.rb +2 -2
- data/lib/{holidays → generated_definitions}/mx.rb +2 -2
- data/lib/{holidays → generated_definitions}/nerc.rb +2 -2
- data/lib/{holidays → generated_definitions}/nl.rb +2 -2
- data/lib/{holidays → generated_definitions}/no.rb +2 -2
- data/lib/{holidays → generated_definitions}/north_america.rb +8 -3
- data/lib/{holidays → generated_definitions}/nyse.rb +2 -2
- data/lib/{holidays → generated_definitions}/nz.rb +5 -5
- data/lib/{holidays → generated_definitions}/ph.rb +2 -2
- data/lib/{holidays → generated_definitions}/pl.rb +2 -2
- data/lib/{holidays → generated_definitions}/pt.rb +2 -2
- data/lib/{holidays → generated_definitions}/ro.rb +2 -2
- data/lib/{holidays → generated_definitions}/scandinavia.rb +2 -2
- data/lib/{holidays → generated_definitions}/se.rb +2 -2
- data/lib/{holidays → generated_definitions}/sg.rb +2 -2
- data/lib/{holidays → generated_definitions}/si.rb +2 -2
- data/lib/{holidays → generated_definitions}/sk.rb +2 -2
- data/lib/{holidays → generated_definitions}/united_nations.rb +2 -2
- data/lib/{holidays → generated_definitions}/ups.rb +8 -3
- data/lib/{holidays → generated_definitions}/us.rb +8 -3
- data/lib/{holidays → generated_definitions}/ve.rb +2 -2
- data/lib/{holidays → generated_definitions}/vi.rb +2 -2
- data/lib/{holidays → generated_definitions}/za.rb +2 -2
- data/lib/holidays.rb +120 -665
- data/lib/holidays/core_extensions/date.rb +39 -0
- data/lib/holidays/date_calculator/day_of_month.rb +68 -0
- data/lib/holidays/date_calculator/easter.rb +58 -0
- data/lib/holidays/date_calculator/weekend_modifier.rb +49 -0
- data/lib/holidays/date_calculator_factory.rb +21 -0
- data/lib/holidays/definition/context/generator.rb +216 -0
- data/lib/holidays/definition/context/merger.rb +26 -0
- data/lib/holidays/definition/repository/cache.rb +33 -0
- data/lib/holidays/definition/repository/holidays_by_month.rb +49 -0
- data/lib/holidays/definition/repository/proc_cache.rb +36 -0
- data/lib/holidays/definition/repository/regions.rb +36 -0
- data/lib/holidays/definition/validator/region.rb +45 -0
- data/lib/holidays/definition_factory.rb +50 -0
- data/lib/holidays/option/context/parse_options.rb +96 -0
- data/lib/holidays/option_factory.rb +14 -0
- data/lib/holidays/use_case/context/between.rb +105 -0
- data/lib/holidays/use_case/context/dates_driver_builder.rb +64 -0
- data/lib/holidays/use_case_factory.rb +20 -0
- data/lib/holidays/version.rb +1 -1
- data/test/defs/test_defs_ar.rb +1 -1
- data/test/defs/test_defs_at.rb +2 -2
- data/test/defs/test_defs_au.rb +61 -43
- data/test/defs/test_defs_be.rb +1 -1
- data/test/defs/test_defs_br.rb +1 -1
- data/test/defs/test_defs_ca.rb +1 -1
- data/test/defs/test_defs_ch.rb +1 -1
- data/test/defs/test_defs_cl.rb +1 -1
- data/test/defs/test_defs_cr.rb +1 -1
- data/test/defs/test_defs_cz.rb +1 -1
- data/test/defs/test_defs_de.rb +18 -30
- data/test/defs/test_defs_dk.rb +1 -1
- data/test/defs/test_defs_ecb_target.rb +3 -3
- data/test/defs/test_defs_el.rb +1 -1
- data/test/defs/test_defs_es.rb +36 -25
- data/test/defs/test_defs_europe.rb +82 -84
- data/test/defs/test_defs_fed_ex.rb +4 -1
- data/test/defs/test_defs_federal_reserve.rb +1 -1
- data/test/defs/test_defs_fi.rb +1 -1
- data/test/defs/test_defs_fr.rb +1 -1
- data/test/defs/test_defs_gb.rb +20 -20
- data/test/defs/test_defs_hr.rb +1 -1
- data/test/defs/test_defs_hu.rb +2 -2
- data/test/defs/test_defs_ie.rb +1 -1
- data/test/defs/test_defs_is.rb +1 -1
- data/test/defs/test_defs_it.rb +1 -1
- data/test/defs/test_defs_jp.rb +1 -1
- data/test/defs/test_defs_li.rb +4 -4
- data/test/defs/test_defs_lt.rb +1 -1
- data/test/defs/test_defs_ma.rb +1 -1
- data/test/defs/test_defs_mx.rb +1 -1
- data/test/defs/test_defs_nerc.rb +1 -1
- data/test/defs/test_defs_nl.rb +1 -1
- data/test/defs/test_defs_no.rb +1 -1
- data/test/defs/test_defs_north_america.rb +5 -3
- data/test/defs/test_defs_nyse.rb +1 -1
- data/test/defs/test_defs_nz.rb +19 -9
- data/test/defs/test_defs_ph.rb +1 -1
- data/test/defs/test_defs_pl.rb +1 -1
- data/test/defs/test_defs_pt.rb +1 -1
- data/test/defs/test_defs_ro.rb +2 -3
- data/test/defs/test_defs_scandinavia.rb +1 -1
- data/test/defs/test_defs_se.rb +1 -1
- data/test/defs/test_defs_sg.rb +1 -1
- data/test/defs/test_defs_si.rb +7 -7
- data/test/defs/test_defs_sk.rb +1 -1
- data/test/defs/test_defs_united_nations.rb +1 -1
- data/test/defs/test_defs_ups.rb +5 -2
- data/test/defs/test_defs_us.rb +5 -3
- data/test/defs/test_defs_ve.rb +1 -1
- data/test/defs/test_defs_vi.rb +1 -1
- data/test/defs/test_defs_za.rb +1 -1
- data/test/{test_date.rb → holidays/core_extensions/test_date.rb} +8 -2
- data/test/holidays/date_calculator/test_day_of_month.rb +27 -0
- data/test/holidays/date_calculator/test_easter.rb +29 -0
- data/test/holidays/date_calculator/test_weekend_modifier.rb +33 -0
- data/test/holidays/definition/context/test_generator.rb +84 -0
- data/test/holidays/definition/context/test_merger.rb +22 -0
- data/test/holidays/definition/repository/test_cache.rb +82 -0
- data/test/holidays/definition/repository/test_holidays_by_month.rb +187 -0
- data/test/holidays/definition/repository/test_proc_cache.rb +29 -0
- data/test/holidays/definition/repository/test_regions.rb +86 -0
- data/test/holidays/definition/validator/test_region.rb +50 -0
- data/test/holidays/option/context/test_parse_options.rb +69 -0
- data/test/holidays/test_date_calculator_factory.rb +21 -0
- data/test/holidays/test_definition_factory.rb +34 -0
- data/test/holidays/test_option_factory.rb +9 -0
- data/test/holidays/test_use_case_factory.rb +13 -0
- data/test/holidays/use_case/context/test_between.rb +75 -0
- data/test/holidays/use_case/context/test_dates_driver_builder.rb +91 -0
- data/test/test_all_regions.rb +14 -3
- data/test/test_helper.rb +2 -1
- data/test/test_holidays.rb +19 -24
- data/test/test_holidays_between.rb +85 -0
- data/test/test_multiple_regions.rb +2 -2
- data/test/test_parse_definitions.rb +10 -4
- metadata +181 -111
- data/.coveralls.yml +0 -1
- data/lib/holidays/MANIFEST +0 -55
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/nl.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/nl'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module NL # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/no.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/no'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module NO # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/ca.yaml, definitions/mx.yaml, definitions/us.yaml, definitions/north_america_informal.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/north_america'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module NORTH_AMERICA # :nodoc:
|
|
@@ -83,7 +83,7 @@ module Holidays
|
|
|
83
83
|
{:wday => 1, :week => 3, :name => "Día de la Revolución", :regions => [:mx]},
|
|
84
84
|
{:mday => 11, :observed => lambda { |date| Holidays.to_weekday_if_weekend(date) }, :observed_id => "to_weekday_if_weekend", :name => "Veterans Day", :regions => [:us]},
|
|
85
85
|
{:wday => 4, :week => 4, :name => "Thanksgiving", :regions => [:us]},
|
|
86
|
-
{:
|
|
86
|
+
{:function => lambda { |year| Holidays.day_after_thanksgiving(year) }, :function_id => "day_after_thanksgiving(year)", :name => "Day after Thanksgiving", :regions => [:us_ca]}],
|
|
87
87
|
12 => [{:mday => 25, :name => "Christmas Day", :regions => [:ca]},
|
|
88
88
|
{:mday => 26, :name => "Boxing Day", :regions => [:ca]},
|
|
89
89
|
{:mday => 12, :type => :informal, :name => "Día de la Virgen de Guadalupe", :regions => [:mx]},
|
|
@@ -116,6 +116,11 @@ def self.us_inauguration_day(year)
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
|
|
119
|
+
def self.day_after_thanksgiving(year)
|
|
120
|
+
Date.calculate_mday(year, 11, 4, 4) + 1
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
119
124
|
|
|
120
125
|
end
|
|
121
126
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/nyse.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/nyse'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module NYSE # :nodoc:
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/nz.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/nz'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module NZ # :nodoc:
|
|
15
15
|
def self.defined_regions
|
|
16
|
-
[:nz, :nz_sl, :nz_we, :nz_ak, :nz_nl, :nz_ot, :nz_sc, :nz_hb, :nz_mb, :nz_ca, :nz_ch, :nz_wl]
|
|
16
|
+
[:nz, :nz_sl, :nz_we, :nz_ak, :nz_nl, :nz_ne, :nz_ot, :nz_ta, :nz_sc, :nz_hb, :nz_mb, :nz_ca, :nz_ch, :nz_wl]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def self.holidays_by_month
|
|
@@ -27,10 +27,10 @@ module Holidays
|
|
|
27
27
|
{:mday => 22, :observed => lambda { |date| Holidays.closest_monday(date) }, :observed_id => "closest_monday", :name => "Wellington Anniversary Day", :regions => [:nz_we]},
|
|
28
28
|
{:mday => 29, :observed => lambda { |date| Holidays.closest_monday(date) }, :observed_id => "closest_monday", :name => "Auckland Anniversary Day", :regions => [:nz_ak]},
|
|
29
29
|
{:mday => 29, :observed => lambda { |date| Holidays.closest_monday(date) }, :observed_id => "closest_monday", :name => "Northland Anniversary Day", :regions => [:nz_nl]}],
|
|
30
|
-
2 => [{:mday => 1, :observed => lambda { |date| Holidays.closest_monday(date) }, :observed_id => "closest_monday", :name => "Nelson Anniversary Day", :regions => [:
|
|
30
|
+
2 => [{:mday => 1, :observed => lambda { |date| Holidays.closest_monday(date) }, :observed_id => "closest_monday", :name => "Nelson Anniversary Day", :regions => [:nz_ne]},
|
|
31
31
|
{:mday => 6, :observed => lambda { |date| Holidays.to_monday_if_weekend(date) }, :observed_id => "to_monday_if_weekend", :name => "Waitangi Day", :regions => [:nz]}],
|
|
32
32
|
3 => [{:mday => 23, :observed => lambda { |date| Holidays.closest_monday(date) }, :observed_id => "closest_monday", :name => "Otago Anniversary Day", :regions => [:nz_ot]},
|
|
33
|
-
{:wday => 1, :week => 2, :name => "Taranaki Anniversary Day", :regions => [:
|
|
33
|
+
{:wday => 1, :week => 2, :observed => lambda { |date| Holidays.closest_monday(date) }, :observed_id => "closest_monday", :name => "Taranaki Anniversary Day", :regions => [:nz_ta]}],
|
|
34
34
|
4 => [{:mday => 25, :observed => lambda { |date| Holidays.to_monday_if_weekend(date) }, :observed_id => "to_monday_if_weekend", :name => "ANZAC Day", :regions => [:nz]}],
|
|
35
35
|
6 => [{:wday => 1, :week => 1, :name => "Queen's Birthday", :regions => [:nz]}],
|
|
36
36
|
9 => [{:wday => 1, :week => 4, :name => "Dominion Day", :regions => [:nz_sc]}],
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/ph.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/ph'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module PH # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/pl.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/pl'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module PL # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/pt.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/pt'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module PT # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/ro.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/ro'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module RO # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/dk.yaml, definitions/is.yaml, definitions/no.yaml, definitions/se.yaml, definitions/fi.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/scandinavia'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module SCANDINAVIA # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/se.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/se'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module SE # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/sg.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/sg'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module SG # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/si.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/si'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module SI # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/sk.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/sk'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module SK # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/united_nations.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/united_nations'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module UNITED_NATIONS # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/ups.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/ups'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module UPS # :nodoc:
|
|
@@ -23,13 +23,18 @@ module Holidays
|
|
|
23
23
|
7 => [{:mday => 4, :observed => lambda { |date| Holidays.to_weekday_if_weekend(date) }, :observed_id => "to_weekday_if_weekend", :name => "Independence Day", :regions => [:ups]}],
|
|
24
24
|
9 => [{:wday => 1, :week => 1, :name => "Labor Day", :regions => [:ups]}],
|
|
25
25
|
11 => [{:wday => 4, :week => 4, :name => "Thanksgiving", :regions => [:ups]},
|
|
26
|
-
{:
|
|
26
|
+
{:function => lambda { |year| Holidays.day_after_thanksgiving(year) }, :function_id => "day_after_thanksgiving(year)", :name => "Day After Thanksgiving", :regions => [:ups]}],
|
|
27
27
|
12 => [{:mday => 25, :observed => lambda { |date| Holidays.to_weekday_if_weekend(date) }, :observed_id => "to_weekday_if_weekend", :name => "Christmas Day", :regions => [:ups]},
|
|
28
28
|
{:mday => 31, :name => "New Year's Eve", :regions => [:ups]}]
|
|
29
29
|
}
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def self.day_after_thanksgiving(year)
|
|
34
|
+
Date.calculate_mday(year, 11, 4, 4) + 1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
33
38
|
|
|
34
39
|
end
|
|
35
40
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/us.yaml, definitions/north_america_informal.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/us'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module US # :nodoc:
|
|
@@ -37,7 +37,7 @@ module Holidays
|
|
|
37
37
|
{:mday => 31, :type => :informal, :name => "Halloween", :regions => [:us, :ca]}],
|
|
38
38
|
11 => [{:mday => 11, :observed => lambda { |date| Holidays.to_weekday_if_weekend(date) }, :observed_id => "to_weekday_if_weekend", :name => "Veterans Day", :regions => [:us]},
|
|
39
39
|
{:wday => 4, :week => 4, :name => "Thanksgiving", :regions => [:us]},
|
|
40
|
-
{:
|
|
40
|
+
{:function => lambda { |year| Holidays.day_after_thanksgiving(year) }, :function_id => "day_after_thanksgiving(year)", :name => "Day after Thanksgiving", :regions => [:us_ca]}],
|
|
41
41
|
12 => [{:mday => 25, :observed => lambda { |date| Holidays.to_weekday_if_weekend(date) }, :observed_id => "to_weekday_if_weekend", :name => "Christmas Day", :regions => [:us]}],
|
|
42
42
|
4 => [{:mday => 1, :type => :informal, :name => "April Fool's Day", :regions => [:us, :ca]},
|
|
43
43
|
{:mday => 22, :type => :informal, :name => "Earth Day", :regions => [:us, :ca]}],
|
|
@@ -52,6 +52,11 @@ def self.us_inauguration_day(year)
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
def self.day_after_thanksgiving(year)
|
|
56
|
+
Date.calculate_mday(year, 11, 4, 4) + 1
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
55
60
|
|
|
56
61
|
end
|
|
57
62
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/ve.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/ve'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module VE # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/vi.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/vi'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module VI # :nodoc:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
module Holidays
|
|
3
3
|
# This file is generated by the Ruby Holidays gem.
|
|
4
4
|
#
|
|
5
|
-
# Definitions loaded:
|
|
5
|
+
# Definitions loaded: definitions/za.yaml
|
|
6
6
|
#
|
|
7
7
|
# To use the definitions in this file, load it right after you load the
|
|
8
8
|
# Holiday gem:
|
|
9
9
|
#
|
|
10
10
|
# require 'holidays'
|
|
11
|
-
# require '
|
|
11
|
+
# require 'generated_definitions/za'
|
|
12
12
|
#
|
|
13
13
|
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
14
14
|
module ZA # :nodoc:
|
data/lib/holidays.rb
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
$:.unshift File.dirname(__FILE__)
|
|
3
3
|
|
|
4
|
-
require 'digest/md5'
|
|
5
4
|
require 'date'
|
|
6
|
-
require '
|
|
5
|
+
require 'holidays/definition_factory'
|
|
6
|
+
require 'holidays/date_calculator_factory'
|
|
7
|
+
require 'holidays/option_factory'
|
|
8
|
+
require 'holidays/use_case_factory'
|
|
7
9
|
|
|
8
10
|
# == Region options
|
|
9
11
|
# Holidays can be defined as belonging to one or more regions and sub regions.
|
|
@@ -47,712 +49,165 @@ module Holidays
|
|
|
47
49
|
# Exception thrown when an unknown region is requested.
|
|
48
50
|
class UnknownRegionError < ArgumentError; end
|
|
49
51
|
|
|
50
|
-
@@regions = []
|
|
51
|
-
@@holidays_by_month = {}
|
|
52
|
-
@@proc_cache = {}
|
|
53
|
-
|
|
54
|
-
@@cache = {}
|
|
55
|
-
@@cache_range = {}
|
|
56
|
-
class << self
|
|
57
|
-
def cache_range; @@cache_range; end
|
|
58
|
-
def cache; @@cache; end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
52
|
WEEKS = {:first => 1, :second => 2, :third => 3, :fourth => 4, :fifth => 5, :last => -1, :second_last => -2, :third_last => -3}
|
|
62
53
|
MONTH_LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
63
54
|
DAY_SYMBOLS = Date::DAYNAMES.collect { |n| n.downcase.intern }
|
|
64
|
-
DEFINITION_PATH = File.expand_path(File.dirname(__FILE__) + '/holidays/')
|
|
65
|
-
|
|
66
|
-
# Get all holidays on a given date.
|
|
67
|
-
#
|
|
68
|
-
# [<tt>date</tt>] A Date object.
|
|
69
|
-
# [<tt>:options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
|
|
70
|
-
#
|
|
71
|
-
# Returns an array of hashes or nil. See Holidays#between for the output
|
|
72
|
-
# format.
|
|
73
|
-
#
|
|
74
|
-
# Also available via Date#holidays.
|
|
75
|
-
def self.on(date, *options)
|
|
76
|
-
self.between(date, date, options)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Does the given work-week have any holidays?
|
|
80
|
-
#
|
|
81
|
-
# [<tt>date</tt>] A Date object.
|
|
82
|
-
# [<tt>:options</tt>] One or more region symbols, and/or <tt>:informal</tt>. Automatically includes <tt>:observed</tt>. If you don't want this, pass <tt>:no_observed</tt>
|
|
83
|
-
#
|
|
84
|
-
# The given Date can be any day of the week.
|
|
85
|
-
# Returns true if any holidays fall on Monday - Friday of the given week.
|
|
86
|
-
def self.full_week?(date, *options)
|
|
87
|
-
days_to_monday = date.wday - 1
|
|
88
|
-
days_to_friday = 5 - date.wday
|
|
89
|
-
start_date = date - days_to_monday
|
|
90
|
-
end_date = date + days_to_friday
|
|
91
|
-
options += [:observed] unless options.include?(:no_observed)
|
|
92
|
-
options.delete(:no_observed)
|
|
93
|
-
self.between(start_date, end_date, options).empty?
|
|
94
|
-
end
|
|
95
55
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
# Returns an array of hashes or nil.
|
|
99
|
-
#
|
|
100
|
-
# Each holiday is returned as a hash with the following fields:
|
|
101
|
-
# [<tt>start_date</tt>] Ruby Date object.
|
|
102
|
-
# [<tt>end_date</tt>] Ruby Date object.
|
|
103
|
-
# [<tt>options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
|
|
104
|
-
#
|
|
105
|
-
# ==== Example
|
|
106
|
-
# from = Date.civil(2008,7,1)
|
|
107
|
-
# to = Date.civil(2008,7,31)
|
|
108
|
-
#
|
|
109
|
-
# Holidays.between(from, to, :ca, :us)
|
|
110
|
-
# => [{:name => 'Canada Day', :regions => [:ca]...}
|
|
111
|
-
# {:name => 'Independence Day'', :regions => [:us], ...}]
|
|
112
|
-
def self.between(start_date, end_date, *options)
|
|
113
|
-
# remove the timezone
|
|
114
|
-
start_date = start_date.new_offset(0) + start_date.offset if start_date.respond_to?(:new_offset)
|
|
115
|
-
end_date = end_date.new_offset(0) + end_date.offset if end_date.respond_to?(:new_offset)
|
|
56
|
+
DEFINITIONS_PATH = 'generated_definitions'
|
|
57
|
+
FULL_DEFINITIONS_PATH = File.expand_path(File.dirname(__FILE__) + "/#{DEFINITIONS_PATH}")
|
|
116
58
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
59
|
+
class << self
|
|
60
|
+
# Get all holidays on a given date.
|
|
61
|
+
#
|
|
62
|
+
# [<tt>date</tt>] A Date object.
|
|
63
|
+
# [<tt>:options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
|
|
64
|
+
#
|
|
65
|
+
# Returns an array of hashes or nil. See Holidays#between for the output
|
|
66
|
+
# format.
|
|
67
|
+
#
|
|
68
|
+
# Also available via Date#holidays.
|
|
69
|
+
def on(date, *options)
|
|
70
|
+
between(date, date, options)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Does the given work-week have any holidays?
|
|
74
|
+
#
|
|
75
|
+
# [<tt>date</tt>] A Date object.
|
|
76
|
+
# [<tt>:options</tt>] One or more region symbols, and/or <tt>:informal</tt>. Automatically includes <tt>:observed</tt>. If you don't want this, pass <tt>:no_observed</tt>
|
|
77
|
+
#
|
|
78
|
+
# The given Date can be any day of the week.
|
|
79
|
+
# Returns true if any holidays fall on Monday - Friday of the given week.
|
|
80
|
+
def full_week?(date, *options)
|
|
81
|
+
days_to_monday = date.wday - 1
|
|
82
|
+
days_to_friday = 5 - date.wday
|
|
83
|
+
start_date = date - days_to_monday
|
|
84
|
+
end_date = date + days_to_friday
|
|
85
|
+
options += [:observed] unless options.include?(:no_observed)
|
|
86
|
+
options.delete(:no_observed)
|
|
87
|
+
between(start_date, end_date, options).empty?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Get all holidays occuring between two dates, inclusively.
|
|
91
|
+
#
|
|
92
|
+
# Returns an array of hashes or nil.
|
|
93
|
+
#
|
|
94
|
+
# Each holiday is returned as a hash with the following fields:
|
|
95
|
+
# [<tt>start_date</tt>] Ruby Date object.
|
|
96
|
+
# [<tt>end_date</tt>] Ruby Date object.
|
|
97
|
+
# [<tt>options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
|
|
98
|
+
#
|
|
99
|
+
# ==== Example
|
|
100
|
+
# from = Date.civil(2008,7,1)
|
|
101
|
+
# to = Date.civil(2008,7,31)
|
|
102
|
+
#
|
|
103
|
+
# Holidays.between(from, to, :ca, :us)
|
|
104
|
+
# => [{:name => 'Canada Day', :regions => [:ca]...}
|
|
105
|
+
# {:name => 'Independence Day'', :regions => [:us], ...}]
|
|
106
|
+
def between(start_date, end_date, *options)
|
|
107
|
+
raise ArgumentError unless start_date && end_date
|
|
108
|
+
|
|
109
|
+
# remove the timezone
|
|
110
|
+
start_date = start_date.new_offset(0) + start_date.offset if start_date.respond_to?(:new_offset)
|
|
111
|
+
end_date = end_date.new_offset(0) + end_date.offset if end_date.respond_to?(:new_offset)
|
|
112
|
+
|
|
113
|
+
start_date, end_date = get_date(start_date), get_date(end_date)
|
|
114
|
+
|
|
115
|
+
if cached_holidays = DefinitionFactory.cache_repository.find(start_date, end_date, options)
|
|
116
|
+
return cached_holidays
|
|
125
117
|
end
|
|
126
|
-
end
|
|
127
118
|
|
|
128
|
-
|
|
129
|
-
|
|
119
|
+
regions, observed, informal = OptionFactory.parse_options.call(options)
|
|
120
|
+
date_driver_hash = UseCaseFactory.dates_driver_builder.call(start_date, end_date)
|
|
130
121
|
|
|
131
|
-
|
|
132
|
-
(start_date..end_date).each do |date|
|
|
133
|
-
# Always include month '0' for variable-month holidays
|
|
134
|
-
dates[date.year] = [0] unless dates[date.year]
|
|
135
|
-
# TODO: test this, maybe should push then flatten
|
|
136
|
-
dates[date.year] << date.month unless dates[date.year].include?(date.month)
|
|
122
|
+
UseCaseFactory.between.call(start_date, end_date, date_driver_hash, regions, observed, informal)
|
|
137
123
|
end
|
|
138
124
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
hbm.each do |h|
|
|
144
|
-
next unless in_region?(regions, h[:regions])
|
|
145
|
-
|
|
146
|
-
# Skip informal holidays unless they have been requested
|
|
147
|
-
next if h[:type] == :informal and not informal
|
|
148
|
-
|
|
149
|
-
if h[:function]
|
|
150
|
-
# Holiday definition requires a calculation
|
|
151
|
-
result = call_proc(h[:function], year)
|
|
152
|
-
|
|
153
|
-
# Procs may return either Date or an integer representing mday
|
|
154
|
-
if result.kind_of?(Date)
|
|
155
|
-
month = result.month
|
|
156
|
-
mday = result.mday
|
|
157
|
-
else
|
|
158
|
-
mday = result
|
|
159
|
-
end
|
|
160
|
-
else
|
|
161
|
-
# Calculate the mday
|
|
162
|
-
mday = h[:mday] || Date.calculate_mday(year, month, h[:week], h[:wday])
|
|
163
|
-
end
|
|
125
|
+
# Allows a developer to explicitly calculate and cache holidays within a given period
|
|
126
|
+
def cache_between(start_date, end_date, *options)
|
|
127
|
+
start_date, end_date = get_date(start_date), get_date(end_date)
|
|
128
|
+
cache_data = between(start_date, end_date, *options)
|
|
164
129
|
|
|
165
|
-
|
|
166
|
-
begin
|
|
167
|
-
date = Date.civil(year, month, mday)
|
|
168
|
-
rescue; next; end
|
|
169
|
-
|
|
170
|
-
# If the :observed option is set, calculate the date when the holiday
|
|
171
|
-
# is observed.
|
|
172
|
-
if observed and h[:observed]
|
|
173
|
-
date = call_proc(h[:observed], date)
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
if date.between?(start_date, end_date)
|
|
177
|
-
holidays << {:date => date, :name => h[:name], :regions => h[:regions]}
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
end
|
|
181
|
-
end
|
|
130
|
+
DefinitionFactory.cache_repository.cache_between(start_date, end_date, cache_data, options)
|
|
182
131
|
end
|
|
183
132
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def self.cache_between(start_date, end_date, *options)
|
|
189
|
-
start_date, end_date = get_date(start_date), get_date(end_date)
|
|
190
|
-
@@cache[options] = between(start_date, end_date, *options)
|
|
191
|
-
@@cache_range[options] = start_date..end_date
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
# Merge a new set of definitions into the Holidays module.
|
|
195
|
-
#
|
|
196
|
-
# This method is automatically called when including holiday definition
|
|
197
|
-
# files.
|
|
198
|
-
def self.merge_defs(regions, holidays) # :nodoc:
|
|
199
|
-
@@regions = @@regions | regions
|
|
200
|
-
@@regions.uniq!
|
|
201
|
-
|
|
202
|
-
holidays.each do |month, holiday_defs|
|
|
203
|
-
@@holidays_by_month[month] = [] unless @@holidays_by_month[month]
|
|
204
|
-
holiday_defs.each do |holiday_def|
|
|
205
|
-
|
|
206
|
-
exists = false
|
|
207
|
-
@@holidays_by_month[month].each do |ex|
|
|
208
|
-
# TODO: gross.
|
|
209
|
-
if ex[:name] == holiday_def[:name] and ex[:wday] == holiday_def[:wday] and ex[:mday] == holiday_def[:mday] and ex[:week] == holiday_def[:week] and ex[:function_id] == holiday_def[:function_id] and ex[:type] == holiday_def[:type] and ex[:observed_id] == holiday_def[:observed_id]
|
|
210
|
-
# append regions
|
|
211
|
-
ex[:regions] << holiday_def[:regions]
|
|
212
|
-
|
|
213
|
-
# Should do this once we're done
|
|
214
|
-
ex[:regions].flatten!
|
|
215
|
-
ex[:regions].uniq!
|
|
216
|
-
exists = true
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
@@holidays_by_month[month] << holiday_def unless exists
|
|
221
|
-
end
|
|
133
|
+
#TODO This should not be publicly available. I need to restructure the public
|
|
134
|
+
# API for this class to something more sensible.
|
|
135
|
+
def merge_defs(regions, holidays) # :nodoc:
|
|
136
|
+
DefinitionFactory.merger.call(regions, holidays)
|
|
222
137
|
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# Get the date of Easter Sunday in a given year. From Easter Sunday, it is
|
|
226
|
-
# possible to calculate many traditional holidays in Western countries.
|
|
227
|
-
# Returns a Date object.
|
|
228
|
-
def self.easter(year)
|
|
229
|
-
y = year
|
|
230
|
-
a = y % 19
|
|
231
|
-
b = y / 100
|
|
232
|
-
c = y % 100
|
|
233
|
-
d = b / 4
|
|
234
|
-
e = b % 4
|
|
235
|
-
f = (b + 8) / 25
|
|
236
|
-
g = (b - f + 1) / 3
|
|
237
|
-
h = (19 * a + b - d - g + 15) % 30
|
|
238
|
-
i = c / 4
|
|
239
|
-
k = c % 4
|
|
240
|
-
l = (32 + 2 * e + 2 * i - h - k) % 7
|
|
241
|
-
m = (a + 11 * h + 22 * l) / 451
|
|
242
|
-
month = (h + l - 7 * m + 114) / 31
|
|
243
|
-
day = ((h + l - 7 * m + 114) % 31) + 1
|
|
244
|
-
Date.civil(year, month, day)
|
|
245
|
-
end
|
|
246
138
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
# Returns a Date object.
|
|
250
|
-
def self.orthodox_easter(year)
|
|
251
|
-
y = year
|
|
252
|
-
g = y % 19
|
|
253
|
-
i = (19 * g + 15) % 30
|
|
254
|
-
j = (year + year/4 + i) % 7
|
|
255
|
-
j_month = 3 + (i - j + 40) / 44
|
|
256
|
-
j_day = i - j + 28 - 31 * (j_month / 4)
|
|
257
|
-
j_date = Date.civil(year, j_month, j_day)
|
|
258
|
-
case
|
|
259
|
-
# up until 1582, julian and gregorian easter dates were identical
|
|
260
|
-
when year <= 1582
|
|
261
|
-
offset = 0
|
|
262
|
-
# between the years 1583 and 1699 10 days are added to the julian day count
|
|
263
|
-
when (year >= 1583 and year <= 1699)
|
|
264
|
-
offset = 10
|
|
265
|
-
# after 1700, 1 day is added for each century, except if the century year is exactly divisible by 400 (in which case no days are added).
|
|
266
|
-
# Safe until 4100 AD, when one leap day will be removed.
|
|
267
|
-
when year >= 1700
|
|
268
|
-
offset = (year - 1700).divmod(100)[0] + ((year - year.divmod(100)[1]).divmod(400)[1] == 0 ? 0 : 1) - (year - year.divmod(100)[1] - 1700).divmod(400)[0] + 10
|
|
139
|
+
def easter(year)
|
|
140
|
+
DateCalculatorFactory.easter_calculator.calculate_easter_for(year)
|
|
269
141
|
end
|
|
270
|
-
# add offset to the julian day
|
|
271
|
-
return Date.jd(j_date.jd + offset)
|
|
272
|
-
end
|
|
273
142
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def self.to_monday_if_sunday(date)
|
|
277
|
-
date += 1 if date.wday == 0
|
|
278
|
-
date
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
# Move date to Monday if it occurs on a Saturday on Sunday.
|
|
282
|
-
# Used as a callback function.
|
|
283
|
-
def self.to_monday_if_weekend(date)
|
|
284
|
-
date += 1 if date.wday == 0
|
|
285
|
-
date += 2 if date.wday == 6
|
|
286
|
-
date
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
# Move Boxing Day if it falls on a weekend, leaving room for Christmas.
|
|
290
|
-
# Used as a callback function.
|
|
291
|
-
def self.to_weekday_if_boxing_weekend(date)
|
|
292
|
-
if date.wday == 6 or date.wday == 0
|
|
293
|
-
date += 2
|
|
294
|
-
elsif date.wday == 1
|
|
295
|
-
date += 1
|
|
143
|
+
def orthodox_easter(year)
|
|
144
|
+
DateCalculatorFactory.easter_calculator.calculate_orthodox_easter_for(year)
|
|
296
145
|
end
|
|
297
|
-
date
|
|
298
|
-
end
|
|
299
146
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
# Used as a callback function.
|
|
303
|
-
def self.to_weekday_if_weekend(date)
|
|
304
|
-
date += 1 if date.wday == 0
|
|
305
|
-
date -= 1 if date.wday == 6
|
|
306
|
-
date
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
# Returns an array of symbols all the available holiday definitions.
|
|
310
|
-
#
|
|
311
|
-
# Optional `full_path` param is used internally for loading all the definitions.
|
|
312
|
-
def self.available(full_path = false)
|
|
313
|
-
paths = Dir.glob(DEFINITION_PATH + '/*.rb')
|
|
314
|
-
full_path ? paths : paths.collect { |path| path.match(/([a-z_-]+)\.rb/i)[1].to_sym }
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
# Returns an array of symbols of all the available holiday regions.
|
|
318
|
-
def self.regions
|
|
319
|
-
@@regions
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
# Load all available holiday definitions
|
|
323
|
-
def self.load_all
|
|
324
|
-
self.available(true).each { |path| require path }
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
# Parses provided holiday definition file(s) and loads them so that they are immediately available.
|
|
328
|
-
def self.load_custom(*files)
|
|
329
|
-
regions, rules_by_month, custom_methods, tests = self.parse_definition_files(files)
|
|
330
|
-
merge_defs(regions, rules_by_month)
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
# Parses provided holiday definition file(s) and returns strings containing the generated module and test source
|
|
334
|
-
def self.parse_definition_files_and_return_source(module_name, *files)
|
|
335
|
-
regions, rules_by_month, custom_methods, tests = self.parse_definition_files(files)
|
|
336
|
-
module_src, test_src = self.generate_definition_source(module_name, files, regions, rules_by_month, custom_methods, tests)
|
|
337
|
-
|
|
338
|
-
return module_src, test_src
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
private
|
|
342
|
-
# Returns [(arr)regions, (bool)observed, (bool)informal]
|
|
343
|
-
def self.parse_options(*options) # :nodoc:
|
|
344
|
-
options.flatten!
|
|
345
|
-
observed = options.delete(:observed) ? true : false
|
|
346
|
-
informal = options.delete(:informal) ? true : false
|
|
347
|
-
regions = parse_regions(options)
|
|
348
|
-
return regions, observed, informal
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
def self.get_date(date)
|
|
352
|
-
if date.respond_to?(:to_date)
|
|
353
|
-
date.to_date
|
|
354
|
-
else
|
|
355
|
-
Date.civil(date.year, date.mon, date.mday)
|
|
147
|
+
def to_monday_if_sunday(date)
|
|
148
|
+
DateCalculatorFactory.weekend_modifier.to_monday_if_sunday(date)
|
|
356
149
|
end
|
|
357
|
-
end
|
|
358
150
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
def self.load_containing_region(sub_reg)
|
|
362
|
-
prefix = sub_reg.split('_').first
|
|
363
|
-
unless @@regions.include?(prefix.to_sym)
|
|
364
|
-
begin
|
|
365
|
-
require "holidays/#{prefix}"
|
|
366
|
-
rescue LoadError
|
|
367
|
-
raise UnknownRegionError, "Could not load holidays/#{prefix}"
|
|
368
|
-
end
|
|
151
|
+
def to_monday_if_weekend(date)
|
|
152
|
+
DateCalculatorFactory.weekend_modifier.to_monday_if_weekend(date)
|
|
369
153
|
end
|
|
370
|
-
end
|
|
371
154
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
#
|
|
375
|
-
# If a wildcard region is found (e.g. <tt>:ca_</tt>) it is expanded into all
|
|
376
|
-
# of its available sub regions.
|
|
377
|
-
def self.parse_regions(regions) # :nodoc:
|
|
378
|
-
regions = [regions] unless regions.kind_of?(Array)
|
|
379
|
-
return [:any] if regions.empty?
|
|
380
|
-
|
|
381
|
-
regions = regions.collect { |r| r.to_sym }
|
|
382
|
-
|
|
383
|
-
# Found sub region wild-card
|
|
384
|
-
regions.delete_if do |r|
|
|
385
|
-
if r.to_s =~ /_$/
|
|
386
|
-
load_containing_region(r.to_s)
|
|
387
|
-
regions << @@regions.select { |dr| dr.to_s =~ Regexp.new("^#{r.to_s}") }
|
|
388
|
-
true
|
|
389
|
-
end
|
|
155
|
+
def to_weekday_if_boxing_weekend(date)
|
|
156
|
+
DateCalculatorFactory.weekend_modifier.to_weekday_if_boxing_weekend(date)
|
|
390
157
|
end
|
|
391
158
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
require "holidays/north_america" if regions.include?(:us) # special case for north_america/US cross-linking
|
|
395
|
-
|
|
396
|
-
regions.each do |r|
|
|
397
|
-
unless r == :any or @@regions.include?(r)
|
|
398
|
-
begin
|
|
399
|
-
require "holidays/#{r.to_s}"
|
|
400
|
-
rescue LoadError => e
|
|
401
|
-
# This could be a sub region that does not have any holiday
|
|
402
|
-
# definitions of its own; try to load the containing region instead.
|
|
403
|
-
if r.to_s =~ /_/
|
|
404
|
-
load_containing_region(r.to_s)
|
|
405
|
-
else
|
|
406
|
-
raise UnknownRegionError, "Could not load holidays/#{r.to_s}"
|
|
407
|
-
end
|
|
408
|
-
end
|
|
409
|
-
end
|
|
159
|
+
def to_weekday_if_boxing_weekend_from_year(year)
|
|
160
|
+
DateCalculatorFactory.weekend_modifier.to_weekday_if_boxing_weekend_from_year(year)
|
|
410
161
|
end
|
|
411
|
-
regions
|
|
412
|
-
end
|
|
413
162
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
# When request :any, all holidays should be returned.
|
|
417
|
-
# When requesting :ca_bc, holidays in :ca or :ca_bc should be returned.
|
|
418
|
-
# When requesting :ca, holidays in :ca but not its subregions should be returned.
|
|
419
|
-
def self.in_region?(requested, available) # :nodoc:
|
|
420
|
-
return true if requested.include?(:any)
|
|
421
|
-
|
|
422
|
-
# When an underscore is encountered, derive the parent regions
|
|
423
|
-
# symbol and include both in the requested array.
|
|
424
|
-
requested = requested.collect do |r|
|
|
425
|
-
r.to_s =~ /_/ ? [r, r.to_s.gsub(/_[\w]*$/, '').to_sym] : r
|
|
163
|
+
def to_weekday_if_weekend(date)
|
|
164
|
+
DateCalculatorFactory.weekend_modifier.to_weekday_if_weekend(date)
|
|
426
165
|
end
|
|
427
166
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
available.any? { |avail| requested.include?(avail) }
|
|
431
|
-
end
|
|
432
|
-
|
|
433
|
-
# Call a proc function defined in a holiday definition file.
|
|
434
|
-
#
|
|
435
|
-
# Procs are cached.
|
|
436
|
-
#
|
|
437
|
-
# ==== Benchmarks
|
|
438
|
-
#
|
|
439
|
-
# Lookup Easter Sunday, with caching, by number of iterations:
|
|
440
|
-
#
|
|
441
|
-
# user system total real
|
|
442
|
-
# 0001 0.000000 0.000000 0.000000 ( 0.000000)
|
|
443
|
-
# 0010 0.000000 0.000000 0.000000 ( 0.000000)
|
|
444
|
-
# 0100 0.078000 0.000000 0.078000 ( 0.078000)
|
|
445
|
-
# 1000 0.641000 0.000000 0.641000 ( 0.641000)
|
|
446
|
-
# 5000 3.172000 0.015000 3.187000 ( 3.219000)
|
|
447
|
-
#
|
|
448
|
-
# Lookup Easter Sunday, without caching, by number of iterations:
|
|
449
|
-
#
|
|
450
|
-
# user system total real
|
|
451
|
-
# 0001 0.000000 0.000000 0.000000 ( 0.000000)
|
|
452
|
-
# 0010 0.016000 0.000000 0.016000 ( 0.016000)
|
|
453
|
-
# 0100 0.125000 0.000000 0.125000 ( 0.125000)
|
|
454
|
-
# 1000 1.234000 0.000000 1.234000 ( 1.234000)
|
|
455
|
-
# 5000 6.094000 0.031000 6.125000 ( 6.141000)
|
|
456
|
-
def self.call_proc(function, year) # :nodoc:
|
|
457
|
-
proc_key = Digest::MD5.hexdigest("#{function.to_s}_#{year.to_s}")
|
|
458
|
-
@@proc_cache[proc_key] = function.call(year) unless @@proc_cache[proc_key]
|
|
459
|
-
@@proc_cache[proc_key]
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
def self.parse_definition_files(files)
|
|
463
|
-
raise ArgumentError, "Must have at least one file to parse" if files.empty?
|
|
464
|
-
|
|
465
|
-
all_regions = []
|
|
466
|
-
all_rules_by_month = {}
|
|
467
|
-
all_custom_methods = {}
|
|
468
|
-
all_tests = []
|
|
469
|
-
|
|
470
|
-
files.flatten!
|
|
471
|
-
|
|
472
|
-
files.each do |file|
|
|
473
|
-
definition_file = YAML.load_file(file)
|
|
474
|
-
|
|
475
|
-
regions, rules_by_month = self.parse_month_definitions(definition_file['months'])
|
|
476
|
-
|
|
477
|
-
all_regions << regions.flatten
|
|
478
|
-
|
|
479
|
-
all_rules_by_month.merge!(rules_by_month) { |month, existing, new|
|
|
480
|
-
existing << new
|
|
481
|
-
existing.flatten!
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
custom_methods = self.parse_method_definitions(definition_file['methods'])
|
|
485
|
-
all_custom_methods.merge!(custom_methods)
|
|
486
|
-
|
|
487
|
-
all_tests << self.parse_test_definitions(definition_file['tests'])
|
|
488
|
-
end
|
|
489
|
-
|
|
490
|
-
all_regions.flatten!.uniq!
|
|
491
|
-
|
|
492
|
-
[all_regions, all_rules_by_month, all_custom_methods, all_tests]
|
|
493
|
-
end
|
|
494
|
-
|
|
495
|
-
def self.parse_month_definitions(month_definitions)
|
|
496
|
-
regions = []
|
|
497
|
-
rules_by_month = {}
|
|
498
|
-
|
|
499
|
-
if month_definitions
|
|
500
|
-
month_definitions.each do |month, definitions|
|
|
501
|
-
rules_by_month[month] = [] unless rules_by_month[month]
|
|
502
|
-
definitions.each do |definition|
|
|
503
|
-
rule = {}
|
|
504
|
-
|
|
505
|
-
definition.each do |key, val|
|
|
506
|
-
rule[key.to_sym] = val
|
|
507
|
-
end
|
|
508
|
-
|
|
509
|
-
rule[:regions] = rule[:regions].collect { |r| r.to_sym }
|
|
510
|
-
|
|
511
|
-
regions << rule[:regions]
|
|
512
|
-
|
|
513
|
-
exists = false
|
|
514
|
-
rules_by_month[month].each do |ex|
|
|
515
|
-
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]
|
|
516
|
-
ex[:regions] << rule[:regions].flatten
|
|
517
|
-
exists = true
|
|
518
|
-
end
|
|
519
|
-
end
|
|
520
|
-
|
|
521
|
-
unless exists
|
|
522
|
-
rules_by_month[month] << rule
|
|
523
|
-
end
|
|
524
|
-
end
|
|
525
|
-
end
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
[regions, rules_by_month]
|
|
529
|
-
end
|
|
530
|
-
|
|
531
|
-
def self.parse_method_definitions(methods)
|
|
532
|
-
custom_methods = {}
|
|
533
|
-
|
|
534
|
-
if methods
|
|
535
|
-
methods.each do |name, code|
|
|
536
|
-
custom_methods[name] = code
|
|
537
|
-
end
|
|
538
|
-
end
|
|
539
|
-
|
|
540
|
-
custom_methods
|
|
541
|
-
end
|
|
542
|
-
|
|
543
|
-
def self.parse_test_definitions(tests)
|
|
544
|
-
test_strings = []
|
|
545
|
-
|
|
546
|
-
if tests
|
|
547
|
-
test_strings << tests
|
|
548
|
-
end
|
|
549
|
-
|
|
550
|
-
test_strings
|
|
551
|
-
end
|
|
552
|
-
|
|
553
|
-
def self.generate_definition_source(module_name, files, regions, rules_by_month, custom_methods, tests)
|
|
554
|
-
month_strings = self.generate_month_definition_strings(rules_by_month)
|
|
555
|
-
|
|
556
|
-
# Build the custom methods string
|
|
557
|
-
custom_method_string = ''
|
|
558
|
-
custom_methods.each do |key, code|
|
|
559
|
-
custom_method_string << code + "\n\n"
|
|
167
|
+
def calculate_day_of_month(year, month, day, wday)
|
|
168
|
+
DateCalculatorFactory.day_of_month_calculator.call(year, month, day, wday)
|
|
560
169
|
end
|
|
561
170
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
def self.generate_month_definition_strings(rules_by_month)
|
|
569
|
-
month_strings = []
|
|
570
|
-
|
|
571
|
-
rules_by_month.each do |month, rules|
|
|
572
|
-
month_string = " #{month.to_s} => ["
|
|
573
|
-
rule_strings = []
|
|
574
|
-
rules.each do |rule|
|
|
575
|
-
string = '{'
|
|
576
|
-
if rule[:mday]
|
|
577
|
-
string << ":mday => #{rule[:mday]}, "
|
|
578
|
-
elsif rule[:function]
|
|
579
|
-
string << ":function => lambda { |year| Holidays.#{rule[:function]} }, "
|
|
580
|
-
string << ":function_id => \"#{rule[:function].to_s}\", "
|
|
581
|
-
else
|
|
582
|
-
string << ":wday => #{rule[:wday]}, :week => #{rule[:week]}, "
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
if rule[:observed]
|
|
586
|
-
string << ":observed => lambda { |date| Holidays.#{rule[:observed]}(date) }, "
|
|
587
|
-
string << ":observed_id => \"#{rule[:observed].to_s}\", "
|
|
588
|
-
end
|
|
589
|
-
|
|
590
|
-
if rule[:type]
|
|
591
|
-
string << ":type => :#{rule[:type]}, "
|
|
592
|
-
end
|
|
593
|
-
|
|
594
|
-
# shouldn't allow the same region twice
|
|
595
|
-
string << ":name => \"#{rule[:name]}\", :regions => [:" + rule[:regions].uniq.join(', :') + "]}"
|
|
596
|
-
rule_strings << string
|
|
597
|
-
end
|
|
598
|
-
month_string << rule_strings.join(",\n ") + "]"
|
|
599
|
-
month_strings << month_string
|
|
171
|
+
# Returns an array of symbols all the available holiday definitions.
|
|
172
|
+
#
|
|
173
|
+
# Optional `full_path` param is used internally for loading all the definitions.
|
|
174
|
+
def available(full_path = false)
|
|
175
|
+
paths = Dir.glob(FULL_DEFINITIONS_PATH + '/*.rb')
|
|
176
|
+
full_path ? paths : paths.collect { |path| path.match(/([a-z_-]+)\.rb/i)[1].to_sym }
|
|
600
177
|
end
|
|
601
178
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
def self.generate_module_src(module_name, files, regions, month_strings, custom_methods)
|
|
606
|
-
module_src = ""
|
|
607
|
-
|
|
608
|
-
module_src =<<-EOM
|
|
609
|
-
# encoding: utf-8
|
|
610
|
-
module Holidays
|
|
611
|
-
# This file is generated by the Ruby Holidays gem.
|
|
612
|
-
#
|
|
613
|
-
# Definitions loaded: #{files.join(', ')}
|
|
614
|
-
#
|
|
615
|
-
# To use the definitions in this file, load it right after you load the
|
|
616
|
-
# Holiday gem:
|
|
617
|
-
#
|
|
618
|
-
# require 'holidays'
|
|
619
|
-
# require 'holidays/#{module_name.to_s.downcase}'
|
|
620
|
-
#
|
|
621
|
-
# All the definitions are available at https://github.com/alexdunae/holidays
|
|
622
|
-
module #{module_name.to_s.upcase} # :nodoc:
|
|
623
|
-
def self.defined_regions
|
|
624
|
-
[:#{regions.join(', :')}]
|
|
179
|
+
# Returns an array of symbols of all the available holiday regions.
|
|
180
|
+
def regions
|
|
181
|
+
DefinitionFactory.regions_repository.all
|
|
625
182
|
end
|
|
626
183
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
184
|
+
# Load all available holiday definitions
|
|
185
|
+
def load_all
|
|
186
|
+
available(true).each { |path| require path }
|
|
631
187
|
end
|
|
632
|
-
end
|
|
633
|
-
|
|
634
|
-
#{custom_methods}
|
|
635
|
-
end
|
|
636
|
-
|
|
637
|
-
Holidays.merge_defs(Holidays::#{module_name.to_s.upcase}.defined_regions, Holidays::#{module_name.to_s.upcase}.holidays_by_month)
|
|
638
|
-
EOM
|
|
639
|
-
|
|
640
|
-
return module_src
|
|
641
|
-
end
|
|
642
|
-
|
|
643
|
-
def self.generate_test_src(module_name, files, tests)
|
|
644
|
-
unless tests.empty?
|
|
645
|
-
test_src = ""
|
|
646
|
-
|
|
647
|
-
test_src =<<-EndOfTests
|
|
648
|
-
# encoding: utf-8
|
|
649
|
-
require File.expand_path(File.dirname(__FILE__)) + '/../test_helper'
|
|
650
|
-
|
|
651
|
-
# This file is generated by the Ruby Holiday gem.
|
|
652
|
-
#
|
|
653
|
-
# Definitions loaded: #{files.join(', ')}
|
|
654
|
-
class #{module_name.to_s.capitalize}DefinitionTests < Test::Unit::TestCase # :nodoc:
|
|
655
188
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
EndOfTests
|
|
189
|
+
# Parses provided holiday definition file(s) and loads them so that they are immediately available.
|
|
190
|
+
def load_custom(*files)
|
|
191
|
+
regions, rules_by_month, custom_methods, tests = DefinitionFactory.file_parser.parse_definition_files(files)
|
|
192
|
+
merge_defs(regions, rules_by_month)
|
|
661
193
|
end
|
|
662
194
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
# === Extending Ruby's Date class with the Holidays gem
|
|
668
|
-
# The Holidays gem automatically extends Ruby's Date class and gives you access
|
|
669
|
-
# to three new methods: holiday?, #holidays and #calculate_mday.
|
|
670
|
-
#
|
|
671
|
-
# ==== Examples
|
|
672
|
-
# Lookup Canada Day in the <tt>:ca</tt> region
|
|
673
|
-
# Date.civil(2008,7,1).holiday?(:ca)
|
|
674
|
-
# => true
|
|
675
|
-
#
|
|
676
|
-
# Lookup Canada Day in the <tt>:fr</tt> region
|
|
677
|
-
# Date.civil(2008,7,1).holiday?(:fr)
|
|
678
|
-
# => false
|
|
679
|
-
#
|
|
680
|
-
# Lookup holidays on North America in January 1.
|
|
681
|
-
# Date.civil(2008,1,1).holidays(:ca, :mx, :us, :informal, :observed)
|
|
682
|
-
# => [{:name => 'New Year\'s Day'...}]
|
|
683
|
-
class Date
|
|
684
|
-
include Holidays
|
|
685
|
-
|
|
686
|
-
# Get holidays on the current date.
|
|
687
|
-
#
|
|
688
|
-
# Returns an array of hashes or nil. See Holidays#between for options
|
|
689
|
-
# and the output format.
|
|
690
|
-
#
|
|
691
|
-
# Date.civil('2008-01-01').holidays(:ca_)
|
|
692
|
-
# => [{:name => 'New Year\'s Day',...}]
|
|
693
|
-
#
|
|
694
|
-
# Also available via Holidays#on.
|
|
695
|
-
def holidays(*options)
|
|
696
|
-
Holidays.on(self, options)
|
|
697
|
-
end
|
|
698
|
-
|
|
699
|
-
# Check if the current date is a holiday.
|
|
700
|
-
#
|
|
701
|
-
# Returns true or false.
|
|
702
|
-
#
|
|
703
|
-
# Date.civil('2008-01-01').holiday?(:ca)
|
|
704
|
-
# => true
|
|
705
|
-
def holiday?(*options)
|
|
706
|
-
holidays = self.holidays(options)
|
|
707
|
-
holidays && !holidays.empty?
|
|
708
|
-
end
|
|
709
|
-
|
|
710
|
-
# Calculate day of the month based on the week number and the day of the
|
|
711
|
-
# week.
|
|
712
|
-
#
|
|
713
|
-
# ==== Parameters
|
|
714
|
-
# [<tt>year</tt>] Integer.
|
|
715
|
-
# [<tt>month</tt>] Integer from 1-12.
|
|
716
|
-
# [<tt>week</tt>] One of <tt>:first</tt>, <tt>:second</tt>, <tt>:third</tt>,
|
|
717
|
-
# <tt>:fourth</tt>, <tt>:fifth</tt> or <tt>:last</tt>.
|
|
718
|
-
# [<tt>wday</tt>] Day of the week as an integer from 0 (Sunday) to 6
|
|
719
|
-
# (Saturday) or as a symbol (e.g. <tt>:monday</tt>).
|
|
720
|
-
#
|
|
721
|
-
# Returns an integer.
|
|
722
|
-
#
|
|
723
|
-
# ===== Examples
|
|
724
|
-
# First Monday of January, 2008:
|
|
725
|
-
# Date.calculate_mday(2008, 1, :first, :monday)
|
|
726
|
-
# => 7
|
|
727
|
-
#
|
|
728
|
-
# Third Thursday of December, 2008:
|
|
729
|
-
# Date.calculate_mday(2008, 12, :third, :thursday)
|
|
730
|
-
# => 18
|
|
731
|
-
#
|
|
732
|
-
# Last Monday of January, 2008:
|
|
733
|
-
# Date.calculate_mday(2008, 1, :last, 1)
|
|
734
|
-
# => 28
|
|
735
|
-
#--
|
|
736
|
-
# see http://www.irt.org/articles/js050/index.htm
|
|
737
|
-
def self.calculate_mday(year, month, week, wday)
|
|
738
|
-
raise ArgumentError, "Week parameter must be one of Holidays::WEEKS (provided #{week})." unless WEEKS.include?(week) or WEEKS.has_value?(week)
|
|
195
|
+
# Parses provided holiday definition file(s) and returns strings containing the generated module and test source
|
|
196
|
+
def parse_definition_files_and_return_source(module_name, *files)
|
|
197
|
+
regions, rules_by_month, custom_methods, tests = DefinitionFactory.file_parser.parse_definition_files(files)
|
|
198
|
+
module_src, test_src = DefinitionFactory.source_generator.generate_definition_source(module_name, files, regions, rules_by_month, custom_methods, tests)
|
|
739
199
|
|
|
740
|
-
|
|
741
|
-
raise ArgumentError, "Wday parameter must be an integer between 0 and 6 or one of Date::DAY_SYMBOLS."
|
|
200
|
+
return module_src, test_src, regions
|
|
742
201
|
end
|
|
743
202
|
|
|
744
|
-
|
|
745
|
-
wday = DAY_SYMBOLS.index(wday) if wday.kind_of?(Symbol)
|
|
203
|
+
private
|
|
746
204
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
205
|
+
def get_date(date)
|
|
206
|
+
if date.respond_to?(:to_date)
|
|
207
|
+
date.to_date
|
|
208
|
+
else
|
|
209
|
+
Date.civil(date.year, date.mon, date.mday)
|
|
210
|
+
end
|
|
750
211
|
end
|
|
751
|
-
|
|
752
|
-
days = MONTH_LENGTHS[month-1]
|
|
753
|
-
|
|
754
|
-
days = 29 if month == 2 and Date.leap?(year)
|
|
755
|
-
|
|
756
|
-
return days - ((Date.civil(year, month, days).wday - wday + 7) % 7) - (7 * (week.abs - 1))
|
|
757
212
|
end
|
|
758
213
|
end
|