holidays 11.5.0 → 11.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +1 -0
- data/lib/generated_definitions/ma.rb +3 -1
- data/lib/generated_definitions/my.rb +3 -1
- data/lib/generated_definitions/northamerica.rb +1 -2
- data/lib/generated_definitions/us.rb +1 -2
- data/lib/holidays/date_calculator/hijri_date.rb +52 -0
- data/lib/holidays/date_calculator/lunar_date.rb +1 -1
- data/lib/holidays/definition/context/merger.rb +6 -1
- data/lib/holidays/definition/custom_methods/ma.rb +48 -0
- data/lib/holidays/definition/custom_methods/my.rb +55 -0
- data/lib/holidays/definition/custom_methods/registry.rb +7 -0
- data/lib/holidays/definition/custom_methods/tr.rb +51 -42
- data/lib/holidays/definition/custom_methods/us.rb +27 -0
- data/lib/holidays/definition/repository/proc_result_cache.rb +4 -0
- data/lib/holidays/factory/date_calculator.rb +6 -1
- data/lib/holidays/factory/definition.rb +2 -0
- data/lib/holidays/finder/context/next_holiday.rb +27 -17
- data/lib/holidays/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a0cce6439fbf9b7dafb577ae8ea715393556a6304fd312ac626c944a1c0ba6da
|
|
4
|
+
data.tar.gz: 9f177f9d50d4c98d74df77f95eed42b3de5f91f1ea52e10c8252ec0f3bf0569f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 23b54b4312a073ef3eab2ee4eb3948ebd91a9b7e6cf33706a1b3105eeb9b3112660649027fce7b6253d17f6a149954b456ab78aac8b8855a08268b2ed739a6eb
|
|
7
|
+
data.tar.gz: 7cc582e293f9d6b2ce9b5b92c715c2e0294eef6986ac04133be3a75cda4bb7fdd0912739794ce0361ab04d29af968983e1bdd14f777e2c85d39e56eb036a4de6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Ruby Holidays Gem CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 11.7.0
|
|
4
|
+
|
|
5
|
+
* Update to [v9.2.0 definitions](https://github.com/holidays/definitions/releases/tag/v9.2.0): `ma` Eid al-Fitr and Eid al-Adha, `my` Hari Raya Puasa and Hari Raya Haji.
|
|
6
|
+
* Add `ma` Eid al-Fitr and Eid al-Adha, calculated from the Hijri calendar. Years where the date proclaimed by the Ministry of Habous and Islamic Affairs differs from the calculation (Eid al-Fitr 2022, Eid al-Adha 2021) use the proclaimed date. [#510](https://github.com/holidays/holidays/pull/510), [#392](https://github.com/holidays/holidays/issues/392)
|
|
7
|
+
* Add `my` Hari Raya Puasa and Hari Raya Haji, calculated from the Hijri calendar. Years where the gazetted date differs from the calculation use the gazetted date, and a holiday falling on a Sunday is observed on the following Monday. [#511](https://github.com/holidays/holidays/pull/511), [#392](https://github.com/holidays/holidays/issues/392)
|
|
8
|
+
* Fix `next_holidays` returning too few holidays and skipping some. It only searched the 12 months after the start date; it now keeps searching later years until enough holidays are found. [#514](https://github.com/holidays/holidays/pull/514), [#513](https://github.com/holidays/holidays/issues/513)
|
|
9
|
+
|
|
10
|
+
## 11.6.0
|
|
11
|
+
|
|
12
|
+
* Update to [v9.1.0 definitions](https://github.com/holidays/definitions/releases/tag/v9.1.0): `tr` feast dates calculated instead of table-driven, `vn` Giỗ Tổ Hùng Vương date fixes, and a region-aware `us` Independence Day observed shift.
|
|
13
|
+
* Calculate `tr` Ramazan Bayramı and Kurban Bayramı from a Hijri calendar instead of a hand-maintained per-year table, so they no longer silently disappear past 2030. [#504](https://github.com/holidays/holidays/pull/504)
|
|
14
|
+
* Fix `vn` Giỗ Tổ Hùng Vương dates for 2018-2023, caused by a lunar calendar leap-month bug in the 2017 table row. [#506](https://github.com/holidays/holidays/pull/506)
|
|
15
|
+
* Add a region-aware `independence_day` observed method for `us` Independence Day, replacing the `us_va`-only shift. Most regions shift to the nearest weekday, `us_ri` shifts to the following Monday, and `us_tx` never shifts. [#508](https://github.com/holidays/holidays/pull/508)
|
|
16
|
+
|
|
3
17
|
## 11.5.0
|
|
4
18
|
|
|
5
19
|
* Update to [v9.0.0 definitions](https://github.com/holidays/definitions/releases/tag/v9.0.0): new `cn` region; `jp`, `kr`, `nz_sl`, `nz_hb`, `ro` date fixes; `tr` feasts through 2030; `de_be` 2025; informal Day of the Dead for `us`/`ca`. The v9.0.0 major is a definitions format change only and does not affect gem results or API.
|
data/README.md
CHANGED
|
@@ -12,7 +12,9 @@ module Holidays
|
|
|
12
12
|
|
|
13
13
|
def self.holidays_by_month
|
|
14
14
|
{
|
|
15
|
-
|
|
15
|
+
0 => [{:function => "eid_al_fitr(year)", :function_arguments => [:year], :name => "Eid al-Fitr", :regions => [:ma]},
|
|
16
|
+
{:function => "eid_al_adha(year)", :function_arguments => [:year], :name => "Eid al-Adha", :regions => [:ma]}],
|
|
17
|
+
1 => [{:mday => 1, :name => "Ras l' âm", :regions => [:ma]},
|
|
16
18
|
{:mday => 11, :name => "Takdim watikat al-istiqlal", :regions => [:ma]}],
|
|
17
19
|
5 => [{:mday => 1, :name => "Eid Ash-Shughl", :regions => [:ma]}],
|
|
18
20
|
7 => [{:mday => 30, :name => "Eid Al-Ârch", :regions => [:ma]}],
|
|
@@ -12,7 +12,9 @@ module Holidays
|
|
|
12
12
|
|
|
13
13
|
def self.holidays_by_month
|
|
14
14
|
{
|
|
15
|
-
|
|
15
|
+
0 => [{:function => "hari_raya_puasa(year)", :function_arguments => [:year], :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "Hari Raya Puasa", :regions => [:my]},
|
|
16
|
+
{:function => "hari_raya_haji(year)", :function_arguments => [:year], :observed => "to_monday_if_sunday(date)", :observed_arguments => [:date], :name => "Hari Raya Haji", :regions => [:my]}],
|
|
17
|
+
1 => [{:mday => 1, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "New Year's Day", :regions => [:my]}],
|
|
16
18
|
5 => [{:mday => 1, :name => "Labour Day", :regions => [:my]}],
|
|
17
19
|
6 => [{:mday => 4, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Agong's Birthday", :regions => [:my]}],
|
|
18
20
|
8 => [{:mday => 31, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Independence Day", :regions => [:my]}],
|
|
@@ -83,8 +83,7 @@ module Holidays
|
|
|
83
83
|
{:mday => 12, :type => :informal, :name => "Orangemen's Day", :regions => [:ca_nl]},
|
|
84
84
|
{:mday => 9, :year_ranges => { :from => 2020 },:observed => "to_monday_if_weekend(date)", :observed_arguments => [:date], :name => "Nunavut Day", :regions => [:ca_nu]},
|
|
85
85
|
{:mday => 3, :name => "Emancipation Day", :regions => [:us_vi]},
|
|
86
|
-
{:mday => 4, :name => "Independence Day", :regions => [:us]},
|
|
87
|
-
{:mday => 4, :function => "to_weekday_if_weekend(date)", :function_arguments => [:date], :name => "Independence Day (Holiday)", :regions => [:us_va]},
|
|
86
|
+
{:mday => 4, :observed => "independence_day(region, date)", :observed_arguments => [:region, :date], :name => "Independence Day", :regions => [:us]},
|
|
88
87
|
{:mday => 24, :name => "Pioneer Day", :regions => [:us_ut]}],
|
|
89
88
|
8 => [{:wday => 1, :week => 1, :name => "B.C. Day", :regions => [:ca_bc]},
|
|
90
89
|
{:wday => 1, :week => 1, :name => "Saskatchewan Day", :regions => [:ca_sk]},
|
|
@@ -58,8 +58,7 @@ module Holidays
|
|
|
58
58
|
{:mday => 20, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "West Virginia Day", :regions => [:us_wv]},
|
|
59
59
|
{:wday => 0, :week => 3, :type => :informal, :name => "Father's Day", :regions => [:us, :ca]}],
|
|
60
60
|
7 => [{:mday => 3, :name => "Emancipation Day", :regions => [:us_vi]},
|
|
61
|
-
{:mday => 4, :name => "Independence Day", :regions => [:us]},
|
|
62
|
-
{:mday => 4, :function => "to_weekday_if_weekend(date)", :function_arguments => [:date], :name => "Independence Day (Holiday)", :regions => [:us_va]},
|
|
61
|
+
{:mday => 4, :observed => "independence_day(region, date)", :observed_arguments => [:region, :date], :name => "Independence Day", :regions => [:us]},
|
|
63
62
|
{:mday => 24, :name => "Pioneer Day", :regions => [:us_ut]}],
|
|
64
63
|
8 => [{:wday => 1, :week => 2, :name => "Victory Day", :regions => [:us_ri]},
|
|
65
64
|
{:mday => 16, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Bennington Battle Day", :regions => [:us_vt]},
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
|
|
3
|
+
module Holidays
|
|
4
|
+
module DateCalculator
|
|
5
|
+
# Arithmetic ("tabular", a.k.a. Kuwaiti) Islamic calendar.
|
|
6
|
+
#
|
|
7
|
+
# Months alternate 30 and 29 days; leap years add a day to the twelfth
|
|
8
|
+
# month on a fixed 11-of-30 cycle. This is a purely arithmetic calendar,
|
|
9
|
+
# so it can land a day (occasionally two) either side of a locally
|
|
10
|
+
# proclaimed date. Callers that need the proclaimed date layer their own
|
|
11
|
+
# override table on top of this (see
|
|
12
|
+
# Holidays::Definition::CustomMethods::TR).
|
|
13
|
+
class HijriDate
|
|
14
|
+
# Julian day number of 1 Muharram 1 AH minus one day, chosen so that
|
|
15
|
+
# to_jd's month/day terms are added directly. Corresponds to the civil
|
|
16
|
+
# epoch (Friday, 16 July 622 CE proleptic Julian).
|
|
17
|
+
EPOCH_JDN = 1948439
|
|
18
|
+
|
|
19
|
+
def to_gregorian(hijri_year, hijri_month, hijri_day)
|
|
20
|
+
Date.jd(to_jd(hijri_year, hijri_month, hijri_day))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Given a Gregorian year and a fixed Hijri month/day, return the
|
|
24
|
+
# occurrence that falls within that Gregorian year, or nil if none does.
|
|
25
|
+
#
|
|
26
|
+
# A fixed Hijri date drifts ~11 days earlier each Gregorian year, so
|
|
27
|
+
# roughly once every 33 years it falls twice in the same Gregorian year
|
|
28
|
+
# (once in early January, once in late December). Only the earlier
|
|
29
|
+
# occurrence is returned.
|
|
30
|
+
def gregorian_year_occurrence(gregorian_year, hijri_month, hijri_day)
|
|
31
|
+
candidate_hijri_year = gregorian_year - 579
|
|
32
|
+
|
|
33
|
+
(candidate_hijri_year - 1..candidate_hijri_year + 1).each do |hijri_year|
|
|
34
|
+
date = to_gregorian(hijri_year, hijri_month, hijri_day)
|
|
35
|
+
return date if date.year == gregorian_year
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def to_jd(year, month, day)
|
|
44
|
+
day +
|
|
45
|
+
(29.5 * (month - 1)).ceil +
|
|
46
|
+
(year - 1) * 354 +
|
|
47
|
+
(3 + 11 * year) / 30 +
|
|
48
|
+
EPOCH_JDN
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -152,7 +152,7 @@ module Holidays
|
|
|
152
152
|
[384, 1, 2, 1, 2, 1, 2, 1, 2, 4, 2, 1, 2].freeze,
|
|
153
153
|
[354, 1, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2, 1].freeze,
|
|
154
154
|
[355, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2].freeze,
|
|
155
|
-
[
|
|
155
|
+
[384, 1, 2, 1, 2, 1, 5, 1, 2, 1, 2, 2, 2].freeze, # 2017 has a leap 6th month; previous entry omitted it, shifting every later date
|
|
156
156
|
[354, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2].freeze,
|
|
157
157
|
[354, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2].freeze,
|
|
158
158
|
[384, 2, 1, 2, 4, 2, 1, 1, 2, 1, 2, 1, 2].freeze,
|
|
@@ -3,10 +3,12 @@ module Holidays
|
|
|
3
3
|
module Context
|
|
4
4
|
# Merge a new set of definitions into the Holidays module.
|
|
5
5
|
class Merger
|
|
6
|
-
def initialize(holidays_by_month_repo, regions_repo, custom_methods_repo)
|
|
6
|
+
def initialize(holidays_by_month_repo, regions_repo, custom_methods_repo, cache_repo, proc_result_cache_repo)
|
|
7
7
|
@holidays_repo = holidays_by_month_repo
|
|
8
8
|
@regions_repo = regions_repo
|
|
9
9
|
@custom_methods_repo = custom_methods_repo
|
|
10
|
+
@cache_repo = cache_repo
|
|
11
|
+
@proc_result_cache_repo = proc_result_cache_repo
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def call(target_regions, target_holidays, target_custom_methods, target_custom_method_sources = {})
|
|
@@ -17,6 +19,9 @@ module Holidays
|
|
|
17
19
|
target_custom_method_sources,
|
|
18
20
|
derive_function_regions(target_holidays),
|
|
19
21
|
)
|
|
22
|
+
ensure
|
|
23
|
+
@cache_repo.reset!
|
|
24
|
+
@proc_result_cache_repo.reset!
|
|
20
25
|
end
|
|
21
26
|
|
|
22
27
|
private
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
|
|
3
|
+
module Holidays
|
|
4
|
+
module Definition
|
|
5
|
+
module CustomMethods
|
|
6
|
+
# ma custom holiday calculations.
|
|
7
|
+
#
|
|
8
|
+
# Eid al-Fitr is 1 Shawwal and Eid al-Adha is 10 Dhul-Hijjah of the
|
|
9
|
+
# Hijri calendar. Both are derived from the arithmetic Islamic calendar
|
|
10
|
+
# (Holidays::DateCalculator::HijriDate). The civil holidays are
|
|
11
|
+
# proclaimed by Morocco's Ministry of Habous and Islamic Affairs and in
|
|
12
|
+
# some years land a day off from the arithmetic result; MINISTRY_OVERRIDES
|
|
13
|
+
# pins those years to the proclaimed date. Years with no entry fall back
|
|
14
|
+
# to the calculation. See holidays#392.
|
|
15
|
+
module MA
|
|
16
|
+
SHAWWAL = 10
|
|
17
|
+
DHU_AL_HIJJAH = 12
|
|
18
|
+
|
|
19
|
+
# Proclaimed first days that differ from the arithmetic calendar,
|
|
20
|
+
# keyed by [feast, gregorian_year]. Sourced from the Ministry of
|
|
21
|
+
# Habous and Islamic Affairs communiques reported via maroc.ma,
|
|
22
|
+
# Hespress, and Morocco World News.
|
|
23
|
+
MINISTRY_OVERRIDES = {
|
|
24
|
+
[:eid_al_fitr, 2022] => Date.new(2022, 5, 2),
|
|
25
|
+
|
|
26
|
+
[:eid_al_adha, 2021] => Date.new(2021, 7, 21),
|
|
27
|
+
}.freeze
|
|
28
|
+
|
|
29
|
+
class << self
|
|
30
|
+
def eid_al_fitr(year)
|
|
31
|
+
feast(:eid_al_fitr, year, SHAWWAL, 1)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def eid_al_adha(year)
|
|
35
|
+
feast(:eid_al_adha, year, DHU_AL_HIJJAH, 10)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def feast(name, year, hijri_month, hijri_day)
|
|
41
|
+
MINISTRY_OVERRIDES[[name, year]] ||
|
|
42
|
+
Holidays::Factory::DateCalculator.hijri_date.gregorian_year_occurrence(year, hijri_month, hijri_day)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
|
|
3
|
+
module Holidays
|
|
4
|
+
module Definition
|
|
5
|
+
module CustomMethods
|
|
6
|
+
# my custom holiday calculations.
|
|
7
|
+
#
|
|
8
|
+
# Hari Raya Puasa (Eid al-Fitr) is 1 Shawwal and Hari Raya Haji (Eid
|
|
9
|
+
# al-Adha) is 10 Dhul-Hijjah of the Hijri calendar. Both are derived
|
|
10
|
+
# from the arithmetic Islamic calendar (Holidays::DateCalculator::HijriDate).
|
|
11
|
+
# The civil holidays are fixed by the Yang di-Pertuan Agong (Conference
|
|
12
|
+
# of Rulers) on JAKIM's moon-sighting advice and in some years have
|
|
13
|
+
# landed a day before the arithmetic result; GAZETTE_OVERRIDES pins
|
|
14
|
+
# those years to the gazetted date. Years with no entry fall back to
|
|
15
|
+
# the calculation. See holidays#392.
|
|
16
|
+
module MY
|
|
17
|
+
SHAWWAL = 10
|
|
18
|
+
DHU_AL_HIJJAH = 12
|
|
19
|
+
|
|
20
|
+
# Gazetted first days that differ from the arithmetic calendar,
|
|
21
|
+
# keyed by [feast, gregorian_year]. Sourced from the official
|
|
22
|
+
# Malaysian public holiday gazette, cross-checked against
|
|
23
|
+
# definitions/sg.yaml (agrees in every overlapping year 2017-2026).
|
|
24
|
+
GAZETTE_OVERRIDES = {
|
|
25
|
+
[:hari_raya_puasa, 2014] => Date.new(2014, 7, 28),
|
|
26
|
+
[:hari_raya_puasa, 2015] => Date.new(2015, 7, 17),
|
|
27
|
+
[:hari_raya_puasa, 2016] => Date.new(2016, 7, 6),
|
|
28
|
+
[:hari_raya_puasa, 2017] => Date.new(2017, 6, 25),
|
|
29
|
+
[:hari_raya_puasa, 2026] => Date.new(2026, 3, 21),
|
|
30
|
+
|
|
31
|
+
[:hari_raya_haji, 2016] => Date.new(2016, 9, 12),
|
|
32
|
+
[:hari_raya_haji, 2017] => Date.new(2017, 9, 1),
|
|
33
|
+
[:hari_raya_haji, 2019] => Date.new(2019, 8, 11),
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
def hari_raya_puasa(year)
|
|
38
|
+
feast(:hari_raya_puasa, year, SHAWWAL, 1)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def hari_raya_haji(year)
|
|
42
|
+
feast(:hari_raya_haji, year, DHU_AL_HIJJAH, 10)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def feast(name, year, hijri_month, hijri_day)
|
|
48
|
+
GAZETTE_OVERRIDES[[name, year]] ||
|
|
49
|
+
Holidays::Factory::DateCalculator.hijri_date.gregorian_year_occurrence(year, hijri_month, hijri_day)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -13,6 +13,8 @@ require 'holidays/definition/custom_methods/is'
|
|
|
13
13
|
require 'holidays/definition/custom_methods/jp'
|
|
14
14
|
require 'holidays/definition/custom_methods/kr'
|
|
15
15
|
require 'holidays/definition/custom_methods/lv'
|
|
16
|
+
require 'holidays/definition/custom_methods/ma'
|
|
17
|
+
require 'holidays/definition/custom_methods/my'
|
|
16
18
|
require 'holidays/definition/custom_methods/nz'
|
|
17
19
|
require 'holidays/definition/custom_methods/ph'
|
|
18
20
|
require 'holidays/definition/custom_methods/se'
|
|
@@ -46,14 +48,19 @@ module Holidays
|
|
|
46
48
|
"columbus_day_cl(year)" => CL.method(:columbus_day_cl).to_proc,
|
|
47
49
|
"day_after_thanksgiving(year)" => FEDEX.method(:day_after_thanksgiving).to_proc,
|
|
48
50
|
"de_buss_und_bettag(year)" => DE.method(:de_buss_und_bettag).to_proc,
|
|
51
|
+
"eid_al_adha(year)" => MA.method(:eid_al_adha).to_proc,
|
|
52
|
+
"eid_al_fitr(year)" => MA.method(:eid_al_fitr).to_proc,
|
|
49
53
|
"election_day(year)" => US.method(:election_day).to_proc,
|
|
50
54
|
"even_year_election_day(year)" => US.method(:even_year_election_day).to_proc,
|
|
51
55
|
"fi_juhannusaatto(year)" => FI.method(:fi_juhannusaatto).to_proc,
|
|
52
56
|
"fi_juhannuspaiva(year)" => FI.method(:fi_juhannuspaiva).to_proc,
|
|
53
57
|
"fi_pyhainpaiva(year)" => FI.method(:fi_pyhainpaiva).to_proc,
|
|
54
58
|
"georgia_state_holiday(year, month)" => US.method(:georgia_state_holiday).to_proc,
|
|
59
|
+
"hari_raya_haji(year)" => MY.method(:hari_raya_haji).to_proc,
|
|
60
|
+
"hari_raya_puasa(year)" => MY.method(:hari_raya_puasa).to_proc,
|
|
55
61
|
"hobart_show_day(year)" => AU.method(:hobart_show_day).to_proc,
|
|
56
62
|
"ie_st_brigids_day(year)" => IE.method(:ie_st_brigids_day).to_proc,
|
|
63
|
+
"independence_day(region, date)" => US.method(:independence_day).to_proc,
|
|
57
64
|
"is_sumardagurinn_fyrsti(year)" => IS.method(:is_sumardagurinn_fyrsti).to_proc,
|
|
58
65
|
"jp_citizens_holiday(year)" => JP.method(:jp_citizens_holiday).to_proc,
|
|
59
66
|
"jp_health_sports_day_substitute(year)" => JP.method(:jp_health_sports_day_substitute).to_proc,
|
|
@@ -3,54 +3,63 @@ require 'date'
|
|
|
3
3
|
module Holidays
|
|
4
4
|
module Definition
|
|
5
5
|
module CustomMethods
|
|
6
|
-
# tr custom holiday calculations
|
|
7
|
-
#
|
|
6
|
+
# tr custom holiday calculations.
|
|
7
|
+
#
|
|
8
|
+
# Ramazan Bayramı is 1 Shawwal and Kurban Bayramı is 10 Dhul-Hijjah of
|
|
9
|
+
# the Hijri calendar. Both are derived from the arithmetic Islamic
|
|
10
|
+
# calendar (Holidays::DateCalculator::HijriDate). The civil holidays are
|
|
11
|
+
# proclaimed by Türkiye's Diyanet and in most years so far have landed a
|
|
12
|
+
# day (2016 Ramazan Bayramı, two days) before the arithmetic result;
|
|
13
|
+
# DIYANET_OVERRIDES pins those years to the proclaimed date. Years with
|
|
14
|
+
# no entry fall back to the calculation. See definitions#377.
|
|
8
15
|
module TR
|
|
16
|
+
SHAWWAL = 10
|
|
17
|
+
DHU_AL_HIJJAH = 12
|
|
18
|
+
|
|
19
|
+
# Proclaimed first days that differ from the arithmetic calendar,
|
|
20
|
+
# keyed by [feast, gregorian_year]. Sourced from the Diyanet dates
|
|
21
|
+
# that the definition file previously carried as a fixed table, plus
|
|
22
|
+
# https://vakithesaplama.diyanet.gov.tr/resmitatiller.php for 2021-2030.
|
|
23
|
+
DIYANET_OVERRIDES = {
|
|
24
|
+
[:ramadan_feast, 2014] => Date.new(2014, 7, 28),
|
|
25
|
+
[:ramadan_feast, 2015] => Date.new(2015, 7, 17),
|
|
26
|
+
[:ramadan_feast, 2016] => Date.new(2016, 7, 5),
|
|
27
|
+
[:ramadan_feast, 2017] => Date.new(2017, 6, 25),
|
|
28
|
+
[:ramadan_feast, 2019] => Date.new(2019, 6, 4),
|
|
29
|
+
[:ramadan_feast, 2022] => Date.new(2022, 5, 2),
|
|
30
|
+
[:ramadan_feast, 2023] => Date.new(2023, 4, 21),
|
|
31
|
+
[:ramadan_feast, 2025] => Date.new(2025, 3, 30),
|
|
32
|
+
[:ramadan_feast, 2027] => Date.new(2027, 3, 9),
|
|
33
|
+
[:ramadan_feast, 2028] => Date.new(2028, 2, 26),
|
|
34
|
+
[:ramadan_feast, 2030] => Date.new(2030, 2, 4),
|
|
35
|
+
|
|
36
|
+
[:sacrifice_feast, 2014] => Date.new(2014, 10, 4),
|
|
37
|
+
[:sacrifice_feast, 2016] => Date.new(2016, 9, 12),
|
|
38
|
+
[:sacrifice_feast, 2017] => Date.new(2017, 9, 1),
|
|
39
|
+
[:sacrifice_feast, 2018] => Date.new(2018, 8, 21),
|
|
40
|
+
[:sacrifice_feast, 2019] => Date.new(2019, 8, 11),
|
|
41
|
+
[:sacrifice_feast, 2022] => Date.new(2022, 7, 9),
|
|
42
|
+
[:sacrifice_feast, 2023] => Date.new(2023, 6, 28),
|
|
43
|
+
[:sacrifice_feast, 2024] => Date.new(2024, 6, 16),
|
|
44
|
+
[:sacrifice_feast, 2025] => Date.new(2025, 6, 6),
|
|
45
|
+
[:sacrifice_feast, 2027] => Date.new(2027, 5, 16),
|
|
46
|
+
[:sacrifice_feast, 2030] => Date.new(2030, 4, 13),
|
|
47
|
+
}.freeze
|
|
48
|
+
|
|
9
49
|
class << self
|
|
10
50
|
def ramadan_feast(year)
|
|
11
|
-
|
|
12
|
-
'2014' => Date.civil(2014, 7, 28),
|
|
13
|
-
'2015' => Date.civil(2015, 7, 17),
|
|
14
|
-
'2016' => Date.civil(2016, 7, 5),
|
|
15
|
-
'2017' => Date.civil(2017, 6, 25),
|
|
16
|
-
'2018' => Date.civil(2018, 6, 15),
|
|
17
|
-
'2019' => Date.civil(2019, 6, 4),
|
|
18
|
-
'2020' => Date.civil(2020, 5, 24),
|
|
19
|
-
'2021' => Date.civil(2021, 5, 13),
|
|
20
|
-
'2022' => Date.civil(2022, 5, 2),
|
|
21
|
-
'2023' => Date.civil(2023, 4, 21),
|
|
22
|
-
'2024' => Date.civil(2024, 4, 10),
|
|
23
|
-
'2025' => Date.civil(2025, 3, 30),
|
|
24
|
-
'2026' => Date.civil(2026, 3, 20),
|
|
25
|
-
'2027' => Date.civil(2027, 3, 9),
|
|
26
|
-
'2028' => Date.civil(2028, 2, 26),
|
|
27
|
-
'2029' => Date.civil(2029, 2, 15),
|
|
28
|
-
'2030' => Date.civil(2030, 2, 4)
|
|
29
|
-
}
|
|
30
|
-
begin_of_ramadan_feast[year.to_s]
|
|
51
|
+
feast(:ramadan_feast, year, SHAWWAL, 1)
|
|
31
52
|
end
|
|
32
53
|
|
|
33
54
|
def sacrifice_feast(year)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
'2021' => Date.civil(2021, 7, 20),
|
|
43
|
-
'2022' => Date.civil(2022, 7, 9),
|
|
44
|
-
'2023' => Date.civil(2023, 6, 28),
|
|
45
|
-
'2024' => Date.civil(2024, 6, 16),
|
|
46
|
-
'2025' => Date.civil(2025, 6, 6),
|
|
47
|
-
'2026' => Date.civil(2026, 5, 27),
|
|
48
|
-
'2027' => Date.civil(2027, 5, 16),
|
|
49
|
-
'2028' => Date.civil(2028, 5, 5),
|
|
50
|
-
'2029' => Date.civil(2029, 4, 24),
|
|
51
|
-
'2030' => Date.civil(2030, 4, 13)
|
|
52
|
-
}
|
|
53
|
-
begin_of_sacrifice_feast[year.to_s]
|
|
55
|
+
feast(:sacrifice_feast, year, DHU_AL_HIJJAH, 10)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def feast(name, year, hijri_month, hijri_day)
|
|
61
|
+
DIYANET_OVERRIDES[[name, year]] ||
|
|
62
|
+
Holidays::Factory::DateCalculator.hijri_date.gregorian_year_occurrence(year, hijri_month, hijri_day)
|
|
54
63
|
end
|
|
55
64
|
end
|
|
56
65
|
end
|
|
@@ -72,6 +72,33 @@ module Holidays
|
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
# Independence Day observed shift, which varies by region:
|
|
76
|
+
# - us_ri: Rhode Island moves to the following Monday on a weekend
|
|
77
|
+
# (Saturday -> +2, Sunday -> +1).
|
|
78
|
+
# - us_tx: Texas does not shift, the date is returned unchanged.
|
|
79
|
+
# - everyone else: nearest weekday, same as +to_weekday_if_weekend+
|
|
80
|
+
# (Saturday -> Friday, Sunday -> Monday).
|
|
81
|
+
def independence_day(region, date)
|
|
82
|
+
if region == :us_ri
|
|
83
|
+
case date.wday
|
|
84
|
+
when 6
|
|
85
|
+
date + 2
|
|
86
|
+
when 0
|
|
87
|
+
date + 1
|
|
88
|
+
else
|
|
89
|
+
date
|
|
90
|
+
end
|
|
91
|
+
elsif region == :us_tx
|
|
92
|
+
date
|
|
93
|
+
elsif date.wday == 6
|
|
94
|
+
date - 1
|
|
95
|
+
elsif date.wday == 0
|
|
96
|
+
date + 1
|
|
97
|
+
else
|
|
98
|
+
date
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
75
102
|
def election_day(year)
|
|
76
103
|
Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 11, 1, 1) + 1
|
|
77
104
|
end
|
|
@@ -2,6 +2,7 @@ require 'holidays/date_calculator/easter'
|
|
|
2
2
|
require 'holidays/date_calculator/weekend_modifier'
|
|
3
3
|
require 'holidays/date_calculator/day_of_month'
|
|
4
4
|
require 'holidays/date_calculator/lunar_date'
|
|
5
|
+
require 'holidays/date_calculator/hijri_date'
|
|
5
6
|
|
|
6
7
|
module Holidays
|
|
7
8
|
module Factory
|
|
@@ -25,10 +26,14 @@ module Holidays
|
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
class << self
|
|
28
|
-
def lunar_date
|
|
29
|
+
def lunar_date
|
|
29
30
|
Holidays::DateCalculator::LunarDate.new
|
|
30
31
|
end
|
|
31
32
|
|
|
33
|
+
def hijri_date
|
|
34
|
+
Holidays::DateCalculator::HijriDate.new
|
|
35
|
+
end
|
|
36
|
+
|
|
32
37
|
def weekend_modifier
|
|
33
38
|
Holidays::DateCalculator::WeekendModifier.new
|
|
34
39
|
end
|
|
@@ -2,6 +2,11 @@ module Holidays
|
|
|
2
2
|
module Finder
|
|
3
3
|
module Context
|
|
4
4
|
class NextHoliday
|
|
5
|
+
# Holidays are searched one 12 month window at a time. The search widens until
|
|
6
|
+
# enough holidays are found or this many years have been searched, which stops
|
|
7
|
+
# a region with no upcoming holidays from being searched forever.
|
|
8
|
+
MAX_YEARS = 50
|
|
9
|
+
|
|
5
10
|
def initialize(definition_search, dates_driver_builder, options_parser)
|
|
6
11
|
@definition_search = definition_search
|
|
7
12
|
@dates_driver_builder = dates_driver_builder
|
|
@@ -12,31 +17,36 @@ module Holidays
|
|
|
12
17
|
validate!(holidays_count, from_date)
|
|
13
18
|
|
|
14
19
|
regions, observed, informal = @options_parser.call(options)
|
|
20
|
+
opts = gather_options(observed, informal)
|
|
15
21
|
|
|
16
22
|
holidays = []
|
|
17
|
-
opts = gather_options(observed, informal)
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
1.upto(MAX_YEARS) do |year|
|
|
25
|
+
holidays.concat(search_window(from_date, year, regions, opts))
|
|
26
|
+
break if holidays.size >= holidays_count
|
|
27
|
+
end
|
|
23
28
|
|
|
24
|
-
|
|
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] }
|
|
29
|
+
holidays.first(holidays_count)
|
|
36
30
|
end
|
|
37
31
|
|
|
38
32
|
private
|
|
39
33
|
|
|
34
|
+
# Windows are contiguous: each starts the day after the previous one ended. The
|
|
35
|
+
# search only looks at the months around a window (plus month 0, which covers the
|
|
36
|
+
# whole year), so dates past the window end are incomplete. They are discarded here
|
|
37
|
+
# and found by the next window instead.
|
|
38
|
+
def search_window(from_date, year, regions, opts)
|
|
39
|
+
window_start = year == 1 ? from_date : (from_date >> 12 * (year - 1)) + 1
|
|
40
|
+
window_end = from_date >> 12 * year
|
|
41
|
+
|
|
42
|
+
dates_driver = @dates_driver_builder.call(window_start, window_end)
|
|
43
|
+
|
|
44
|
+
@definition_search
|
|
45
|
+
.call(dates_driver, regions, opts)
|
|
46
|
+
.select { |holiday| (window_start..window_end).cover?(holiday[:date]) }
|
|
47
|
+
.sort_by { |holiday| holiday[:date] }
|
|
48
|
+
end
|
|
49
|
+
|
|
40
50
|
def validate!(holidays_count, from_date)
|
|
41
51
|
raise ArgumentError unless holidays_count
|
|
42
52
|
raise ArgumentError if holidays_count <= 0
|
data/lib/holidays/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: holidays
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 11.
|
|
4
|
+
version: 11.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Dunae
|
|
@@ -197,6 +197,7 @@ files:
|
|
|
197
197
|
- lib/holidays/core_extensions/time.rb
|
|
198
198
|
- lib/holidays/date_calculator/day_of_month.rb
|
|
199
199
|
- lib/holidays/date_calculator/easter.rb
|
|
200
|
+
- lib/holidays/date_calculator/hijri_date.rb
|
|
200
201
|
- lib/holidays/date_calculator/lunar_date.rb
|
|
201
202
|
- lib/holidays/date_calculator/weekend_modifier.rb
|
|
202
203
|
- lib/holidays/definition/context/function_processor.rb
|
|
@@ -218,6 +219,8 @@ files:
|
|
|
218
219
|
- lib/holidays/definition/custom_methods/jp.rb
|
|
219
220
|
- lib/holidays/definition/custom_methods/kr.rb
|
|
220
221
|
- lib/holidays/definition/custom_methods/lv.rb
|
|
222
|
+
- lib/holidays/definition/custom_methods/ma.rb
|
|
223
|
+
- lib/holidays/definition/custom_methods/my.rb
|
|
221
224
|
- lib/holidays/definition/custom_methods/nz.rb
|
|
222
225
|
- lib/holidays/definition/custom_methods/ph.rb
|
|
223
226
|
- lib/holidays/definition/custom_methods/registry.rb
|