calendarium-romanum 0.3.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +47 -0
- data/.travis.yml +20 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +340 -0
- data/Gemfile +25 -0
- data/Gemfile.lock +86 -0
- data/README.md +515 -0
- data/Rakefile +9 -0
- data/bin/calendariumrom +4 -1
- data/calendarium-romanum.gemspec +26 -0
- data/config/locales/cs.yml +17 -1
- data/config/locales/en.yml +28 -14
- data/config/locales/es.yml +90 -0
- data/config/locales/fr.yml +90 -0
- data/config/locales/it.yml +18 -2
- data/config/locales/la.yml +17 -1
- data/data/README.md +43 -1
- data/data/czech-brno-cs.txt +4 -6
- data/data/czech-budejovice-cs.txt +4 -6
- data/data/czech-cechy-cs.txt +4 -5
- data/data/czech-cs.txt +237 -234
- data/data/czech-hradec-cs.txt +3 -5
- data/data/czech-litomerice-cs.txt +5 -7
- data/data/czech-morava-cs.txt +4 -5
- data/data/czech-olomouc-cs.txt +2 -4
- data/data/czech-ostrava-cs.txt +3 -5
- data/data/czech-plzen-cs.txt +3 -5
- data/data/czech-praha-cs.txt +3 -4
- data/data/universal-en.txt +214 -211
- data/data/universal-es.txt +243 -0
- data/data/universal-fr.txt +243 -0
- data/data/universal-it.txt +214 -211
- data/data/universal-la.txt +214 -210
- data/doc/data_readme.md +2 -0
- data/doc/images/class_diagram.png +0 -0
- data/doc/images/class_diagram.puml +44 -0
- data/doc/yard_readme.rdoc +76 -0
- data/lib/calendarium-romanum.rb +30 -21
- data/lib/calendarium-romanum/abstract_date.rb +12 -0
- data/lib/calendarium-romanum/calendar.rb +207 -52
- data/lib/calendarium-romanum/cli.rb +101 -52
- data/lib/calendarium-romanum/cr.rb +16 -0
- data/lib/calendarium-romanum/data.rb +46 -18
- data/lib/calendarium-romanum/day.rb +202 -20
- data/lib/calendarium-romanum/enum.rb +24 -5
- data/lib/calendarium-romanum/enums.rb +102 -36
- data/lib/calendarium-romanum/errors.rb +4 -0
- data/lib/calendarium-romanum/ordinalizer.rb +30 -6
- data/lib/calendarium-romanum/perpetual_calendar.rb +97 -0
- data/lib/calendarium-romanum/rank.rb +43 -6
- data/lib/calendarium-romanum/sanctorale.rb +170 -24
- data/lib/calendarium-romanum/sanctorale_factory.rb +74 -3
- data/lib/calendarium-romanum/sanctorale_loader.rb +176 -0
- data/lib/calendarium-romanum/temporale.rb +251 -119
- data/lib/calendarium-romanum/temporale/celebration_factory.rb +106 -0
- data/lib/calendarium-romanum/temporale/dates.rb +117 -36
- data/lib/calendarium-romanum/temporale/extensions/christ_eternal_priest.rb +18 -6
- data/lib/calendarium-romanum/transfers.rb +20 -1
- data/lib/calendarium-romanum/util.rb +36 -3
- data/lib/calendarium-romanum/version.rb +5 -1
- metadata +29 -21
- data/lib/calendarium-romanum/sanctoraleloader.rb +0 -115
- data/spec/abstract_date_spec.rb +0 -62
- data/spec/calendar_spec.rb +0 -352
- data/spec/cli_spec.rb +0 -26
- data/spec/data_spec.rb +0 -23
- data/spec/date_spec.rb +0 -61
- data/spec/dates_spec.rb +0 -45
- data/spec/enum_spec.rb +0 -51
- data/spec/i18n_spec.rb +0 -59
- data/spec/rank_spec.rb +0 -42
- data/spec/readme_spec.rb +0 -52
- data/spec/sanctorale_factory_spec.rb +0 -42
- data/spec/sanctorale_spec.rb +0 -167
- data/spec/sanctoraleloader_spec.rb +0 -171
- data/spec/spec_helper.rb +0 -35
- data/spec/temporale_spec.rb +0 -500
@@ -0,0 +1,106 @@
|
|
1
|
+
module CalendariumRomanum
|
2
|
+
class Temporale
|
3
|
+
# Provides factory methods building {Celebration}s
|
4
|
+
# for temporale feasts
|
5
|
+
class CelebrationFactory
|
6
|
+
class << self
|
7
|
+
# @yield [Symbol]
|
8
|
+
# @return [void, Enumerator]
|
9
|
+
def each
|
10
|
+
return to_enum(__method__) unless block_given?
|
11
|
+
|
12
|
+
celebrations.each do |symbol|
|
13
|
+
yield public_send(symbol)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Celebration]
|
18
|
+
def first_advent_sunday
|
19
|
+
Temporale.create_celebration(
|
20
|
+
I18n.t('temporale.advent.sunday', week: Ordinalizer.ordinal(1)),
|
21
|
+
Ranks::PRIMARY,
|
22
|
+
Colours::VIOLET
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def celebrations
|
29
|
+
@celebrations ||= [:first_advent_sunday]
|
30
|
+
end
|
31
|
+
|
32
|
+
def celebration(symbol, rank, colour = Colours::WHITE, fixed_date: false)
|
33
|
+
define_singleton_method(symbol) do
|
34
|
+
Temporale.create_celebration(
|
35
|
+
proc { I18n.t("temporale.solemnity.#{symbol}") },
|
36
|
+
rank,
|
37
|
+
colour,
|
38
|
+
symbol: symbol,
|
39
|
+
date: fixed_date
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
celebrations << symbol
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Celebration]
|
48
|
+
# @!scope class
|
49
|
+
celebration(:nativity, Ranks::PRIMARY, fixed_date: AbstractDate.new(12, 25))
|
50
|
+
# @return [Celebration]
|
51
|
+
# @!scope class
|
52
|
+
celebration(:holy_family, Ranks::FEAST_LORD_GENERAL)
|
53
|
+
# @return [Celebration]
|
54
|
+
# @!scope class
|
55
|
+
celebration(:mother_of_god, Ranks::SOLEMNITY_GENERAL, fixed_date: AbstractDate.new(1, 1))
|
56
|
+
# @return [Celebration]
|
57
|
+
# @!scope class
|
58
|
+
celebration(:epiphany, Ranks::PRIMARY)
|
59
|
+
# @return [Celebration]
|
60
|
+
# @!scope class
|
61
|
+
celebration(:baptism_of_lord, Ranks::FEAST_LORD_GENERAL)
|
62
|
+
# @return [Celebration]
|
63
|
+
# @!scope class
|
64
|
+
celebration(:ash_wednesday, Ranks::PRIMARY, Colours::VIOLET)
|
65
|
+
# @return [Celebration]
|
66
|
+
# @!scope class
|
67
|
+
celebration(:good_friday, Ranks::TRIDUUM, Colours::RED)
|
68
|
+
# @return [Celebration]
|
69
|
+
# @!scope class
|
70
|
+
celebration(:holy_saturday, Ranks::TRIDUUM, Colours::VIOLET)
|
71
|
+
# @return [Celebration]
|
72
|
+
# @!scope class
|
73
|
+
celebration(:palm_sunday, Ranks::PRIMARY, Colours::RED)
|
74
|
+
# @return [Celebration]
|
75
|
+
# @!scope class
|
76
|
+
celebration(:easter_sunday, Ranks::TRIDUUM)
|
77
|
+
# @return [Celebration]
|
78
|
+
# @!scope class
|
79
|
+
celebration(:ascension, Ranks::PRIMARY)
|
80
|
+
# @return [Celebration]
|
81
|
+
# @!scope class
|
82
|
+
celebration(:pentecost, Ranks::PRIMARY, Colours::RED)
|
83
|
+
# @return [Celebration]
|
84
|
+
# @!scope class
|
85
|
+
celebration(:holy_trinity, Ranks::SOLEMNITY_GENERAL)
|
86
|
+
# @return [Celebration]
|
87
|
+
# @!scope class
|
88
|
+
celebration(:corpus_christi, Ranks::SOLEMNITY_GENERAL)
|
89
|
+
# @return [Celebration]
|
90
|
+
# @!scope class
|
91
|
+
celebration(:sacred_heart, Ranks::SOLEMNITY_GENERAL)
|
92
|
+
# @return [Celebration]
|
93
|
+
# @!scope class
|
94
|
+
celebration(:christ_king, Ranks::SOLEMNITY_GENERAL)
|
95
|
+
# @return [Celebration]
|
96
|
+
# @!scope class
|
97
|
+
celebration(:mother_of_church, Ranks::MEMORIAL_GENERAL)
|
98
|
+
# @return [Celebration]
|
99
|
+
# @!scope class
|
100
|
+
celebration(:immaculate_heart, Ranks::MEMORIAL_GENERAL)
|
101
|
+
# @return [Celebration]
|
102
|
+
# @!scope class
|
103
|
+
celebration(:saturday_memorial_bvm, Ranks::MEMORIAL_OPTIONAL)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
module CalendariumRomanum
|
2
2
|
class Temporale
|
3
|
-
# dates of movable feasts
|
3
|
+
# Provides methods computing dates of movable feasts
|
4
|
+
# and utilities for common computations of relative dates
|
4
5
|
module Dates
|
6
|
+
# (see .nativity)
|
5
7
|
def self.first_advent_sunday(year)
|
6
|
-
sunday_before(nativity(year)) - 3 *
|
8
|
+
sunday_before(nativity(year)) - 3 * WEEK
|
7
9
|
end
|
8
10
|
|
11
|
+
# @param year [Fixnum] liturgical year
|
12
|
+
# @return [Date]
|
9
13
|
def self.nativity(year)
|
10
14
|
Date.new(year, 12, 25)
|
11
15
|
end
|
12
16
|
|
17
|
+
# (see .nativity)
|
13
18
|
def self.holy_family(year)
|
14
19
|
xmas = nativity(year)
|
15
20
|
if xmas.sunday?
|
@@ -19,22 +24,41 @@ module CalendariumRomanum
|
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
27
|
+
# (see .nativity)
|
22
28
|
def self.mother_of_god(year)
|
23
29
|
octave_of(nativity(year))
|
24
30
|
end
|
25
31
|
|
26
|
-
|
27
|
-
|
32
|
+
# @param year [Fixnum] liturgical year
|
33
|
+
# @param sunday [Boolean] transfer to Sunday?
|
34
|
+
# @return [Date]
|
35
|
+
def self.epiphany(year, sunday: false)
|
36
|
+
if sunday
|
37
|
+
# GNLYC 7 a)
|
38
|
+
return sunday_after(Date.new(year + 1, 1, 1))
|
39
|
+
end
|
40
|
+
|
41
|
+
Date.new(year + 1, 1, 6)
|
28
42
|
end
|
29
43
|
|
30
|
-
|
31
|
-
|
44
|
+
# @param year [Fixnum] liturgical year
|
45
|
+
# @param epiphany_on_sunday [Boolean] was Epiphany transferred to Sunday?
|
46
|
+
# @return [Date]
|
47
|
+
def self.baptism_of_lord(year, epiphany_on_sunday: false)
|
48
|
+
e = epiphany(year, sunday: epiphany_on_sunday)
|
49
|
+
if epiphany_on_sunday
|
50
|
+
e + 1
|
51
|
+
else
|
52
|
+
sunday_after e
|
53
|
+
end
|
32
54
|
end
|
33
55
|
|
56
|
+
# (see .nativity)
|
34
57
|
def self.ash_wednesday(year)
|
35
|
-
easter_sunday(year) - (6 *
|
58
|
+
easter_sunday(year) - (6 * WEEK + 4)
|
36
59
|
end
|
37
60
|
|
61
|
+
# (see .nativity)
|
38
62
|
def self.easter_sunday(year)
|
39
63
|
year += 1
|
40
64
|
|
@@ -42,100 +66,157 @@ module CalendariumRomanum
|
|
42
66
|
# https://github.com/jrobertson/easter
|
43
67
|
|
44
68
|
golden_number = (year % 19) + 1
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
else
|
50
|
-
# Gregorian calendar
|
51
|
-
dominical_number = (year + (year / 4) - (year / 100) + (year / 400)) % 7
|
52
|
-
solar_correction = (year - 1600) / 100 - (year - 1600) / 400
|
53
|
-
lunar_correction = (((year - 1400) / 100) * 8) / 25
|
54
|
-
paschal_full_moon = (3 - 11 * golden_number + solar_correction - lunar_correction) % 30
|
55
|
-
end
|
69
|
+
dominical_number = (year + (year / 4) - (year / 100) + (year / 400)) % 7
|
70
|
+
solar_correction = (year - 1600) / 100 - (year - 1600) / 400
|
71
|
+
lunar_correction = (((year - 1400) / 100) * 8) / 25
|
72
|
+
paschal_full_moon = (3 - 11 * golden_number + solar_correction - lunar_correction) % 30
|
56
73
|
dominical_number += 7 until dominical_number > 0
|
57
74
|
paschal_full_moon += 30 until paschal_full_moon > 0
|
58
|
-
paschal_full_moon -= 1 if paschal_full_moon == 29
|
75
|
+
paschal_full_moon -= 1 if (paschal_full_moon == 29) || ((paschal_full_moon == 28) && golden_number > 11)
|
59
76
|
difference = (4 - paschal_full_moon - dominical_number) % 7
|
60
77
|
difference += 7 if difference < 0
|
61
78
|
day_easter = paschal_full_moon + difference + 1
|
62
|
-
if day_easter < 11
|
79
|
+
if day_easter < 11
|
63
80
|
# Easter occurs in March.
|
64
|
-
return Date.new(
|
81
|
+
return Date.new(year, 3, day_easter + 21)
|
65
82
|
else
|
66
83
|
# Easter occurs in April.
|
67
|
-
return Date.new(
|
84
|
+
return Date.new(year, 4, day_easter - 10)
|
68
85
|
end
|
69
86
|
end
|
70
87
|
|
88
|
+
# (see .nativity)
|
71
89
|
def self.palm_sunday(year)
|
72
90
|
easter_sunday(year) - 7
|
73
91
|
end
|
74
92
|
|
93
|
+
# (see .nativity)
|
75
94
|
def self.good_friday(year)
|
76
95
|
easter_sunday(year) - 2
|
77
96
|
end
|
78
97
|
|
98
|
+
# (see .nativity)
|
79
99
|
def self.holy_saturday(year)
|
80
100
|
easter_sunday(year) - 1
|
81
101
|
end
|
82
102
|
|
83
|
-
|
103
|
+
# (see .epiphany)
|
104
|
+
def self.ascension(year, sunday: false)
|
105
|
+
if sunday
|
106
|
+
# GNLYC 7 b)
|
107
|
+
return easter_sunday(year) + 6 * WEEK
|
108
|
+
end
|
109
|
+
|
84
110
|
pentecost(year) - 10
|
85
111
|
end
|
86
112
|
|
113
|
+
# (see .nativity)
|
87
114
|
def self.pentecost(year)
|
88
|
-
easter_sunday(year) + 7 *
|
115
|
+
easter_sunday(year) + 7 * WEEK
|
89
116
|
end
|
90
117
|
|
118
|
+
# (see .nativity)
|
91
119
|
def self.holy_trinity(year)
|
92
120
|
octave_of(pentecost(year))
|
93
121
|
end
|
94
122
|
|
95
|
-
|
123
|
+
# (see .epiphany)
|
124
|
+
def self.corpus_christi(year, sunday: false)
|
125
|
+
if sunday
|
126
|
+
# GNLYC 7 c)
|
127
|
+
return holy_trinity(year) + WEEK
|
128
|
+
end
|
129
|
+
|
96
130
|
holy_trinity(year) + 4
|
97
131
|
end
|
98
132
|
|
133
|
+
# (see .nativity)
|
99
134
|
def self.sacred_heart(year)
|
100
|
-
|
135
|
+
corpus_christi(year) + 8
|
136
|
+
end
|
137
|
+
|
138
|
+
# (see .nativity)
|
139
|
+
def self.mother_of_church(year)
|
140
|
+
pentecost(year) + 1
|
101
141
|
end
|
102
142
|
|
143
|
+
# (see .nativity)
|
103
144
|
def self.immaculate_heart(year)
|
104
145
|
pentecost(year) + 20
|
105
146
|
end
|
106
147
|
|
148
|
+
# (see .nativity)
|
107
149
|
def self.christ_king(year)
|
108
150
|
first_advent_sunday(year + 1) - 7
|
109
151
|
end
|
110
152
|
|
111
153
|
# utility methods
|
112
154
|
|
155
|
+
# @param weekday [Fixnum]
|
156
|
+
# @param date [Date]
|
157
|
+
# @return [Date]
|
113
158
|
def self.weekday_before(weekday, date)
|
114
|
-
if date.wday == weekday
|
115
|
-
|
159
|
+
if date.wday == weekday
|
160
|
+
date - WEEK
|
116
161
|
elsif weekday < date.wday
|
117
|
-
|
162
|
+
date - (date.wday - weekday)
|
118
163
|
else
|
119
|
-
|
164
|
+
date - (date.wday + WEEK - weekday)
|
120
165
|
end
|
121
166
|
end
|
122
167
|
|
168
|
+
# (see .weekday_before)
|
123
169
|
def self.weekday_after(weekday, date)
|
124
|
-
if date.wday == weekday
|
125
|
-
|
170
|
+
if date.wday == weekday
|
171
|
+
date + WEEK
|
126
172
|
elsif weekday > date.wday
|
127
|
-
|
173
|
+
date + (weekday - date.wday)
|
128
174
|
else
|
129
|
-
|
175
|
+
date + (WEEK - date.wday + weekday)
|
130
176
|
end
|
131
177
|
end
|
132
178
|
|
179
|
+
# @param date [Date]
|
180
|
+
# @return [Date]
|
133
181
|
def self.octave_of(date)
|
134
|
-
date +
|
182
|
+
date + WEEK
|
135
183
|
end
|
136
184
|
|
137
185
|
class << self
|
138
|
-
|
186
|
+
# @!method sunday_before(date)
|
187
|
+
# @param date [Date]
|
188
|
+
# @return [Date]
|
189
|
+
# @!method monday_before(date)
|
190
|
+
# (see .sunday_before)
|
191
|
+
# @!method tuesday_before(date)
|
192
|
+
# (see .sunday_before)
|
193
|
+
# @!method wednesday_before(date)
|
194
|
+
# (see .sunday_before)
|
195
|
+
# @!method thursday_before(date)
|
196
|
+
# (see .sunday_before)
|
197
|
+
# @!method friday_before(date)
|
198
|
+
# (see .sunday_before)
|
199
|
+
# @!method saturday_before(date)
|
200
|
+
# (see .sunday_before)
|
201
|
+
|
202
|
+
# @!method sunday_after(date)
|
203
|
+
# @param date [Date]
|
204
|
+
# @return [Date]
|
205
|
+
# @!method monday_after(date)
|
206
|
+
# (see .sunday_after)
|
207
|
+
# @!method tuesday_after(date)
|
208
|
+
# (see .sunday_after)
|
209
|
+
# @!method wednesday_after(date)
|
210
|
+
# (see .sunday_after)
|
211
|
+
# @!method thursday_after(date)
|
212
|
+
# (see .sunday_after)
|
213
|
+
# @!method friday_after(date)
|
214
|
+
# (see .sunday_after)
|
215
|
+
# @!method saturday_after(date)
|
216
|
+
# (see .sunday_after)
|
217
|
+
|
218
|
+
# @api private
|
219
|
+
WEEKDAYS = %w(sunday monday tuesday wednesday thursday friday saturday).freeze
|
139
220
|
WEEKDAYS.each_with_index do |weekday, weekday_i|
|
140
221
|
define_method "#{weekday}_before" do |date|
|
141
222
|
send('weekday_before', weekday_i, date)
|
@@ -1,11 +1,20 @@
|
|
1
1
|
module CalendariumRomanum
|
2
2
|
class Temporale
|
3
3
|
module Extensions
|
4
|
-
# Temporale extension adding
|
4
|
+
# {Temporale} extension adding the movable feast
|
5
|
+
# of "Christ Eternal Priests",
|
5
6
|
# included in some local calendars
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# temporale = Temporale.new(2015, extensions: [
|
10
|
+
# Temporale::Extensions::ChristEternalPriest
|
11
|
+
# ])
|
6
12
|
module ChristEternalPriest
|
7
|
-
|
8
|
-
|
13
|
+
# @yield [Symbol, Celebration]
|
14
|
+
# @return [void]
|
15
|
+
def self.each_celebration
|
16
|
+
yield(
|
17
|
+
# symbol refers to the date-computing method
|
9
18
|
:christ_eternal_priest,
|
10
19
|
Celebration.new(
|
11
20
|
proc { I18n.t('temporale.extension.christ_eternal_priest') },
|
@@ -15,9 +24,12 @@ module CalendariumRomanum
|
|
15
24
|
)
|
16
25
|
end
|
17
26
|
|
18
|
-
#
|
19
|
-
|
20
|
-
|
27
|
+
# Computes the feast's date
|
28
|
+
#
|
29
|
+
# @param year [Fixnum] liturgical year
|
30
|
+
# @return [Date]
|
31
|
+
def self.christ_eternal_priest(year)
|
32
|
+
Dates.pentecost(year) + 4
|
21
33
|
end
|
22
34
|
end
|
23
35
|
end
|
@@ -1,7 +1,22 @@
|
|
1
1
|
module CalendariumRomanum
|
2
2
|
|
3
|
-
#
|
3
|
+
# Internal {Calendar} component.
|
4
|
+
# Resolves transfers of conflicting solemnities.
|
5
|
+
#
|
6
|
+
# For any day {Temporale} has a {Celebration}.
|
7
|
+
# Often {Sanctorale} has one (or more), too.
|
8
|
+
# {Calendar} handles these conflicts, in most cases
|
9
|
+
# by throwing away all the proposed {Celebration}s except
|
10
|
+
# of the one of highest rank.
|
11
|
+
# But when there are two conflicting _solemnities_,
|
12
|
+
# one is celebrated on the given day and the less lucky one
|
13
|
+
# must be transferred to another day.
|
14
|
+
# However, not all days are valid as targets of solemnity transfer.
|
15
|
+
#
|
16
|
+
# @api private
|
4
17
|
class Transfers
|
18
|
+
# @param temporale [Temporale]
|
19
|
+
# @param sanctorale [Sanctorale]
|
5
20
|
def initialize(temporale, sanctorale)
|
6
21
|
@transferred = {}
|
7
22
|
@temporale = temporale
|
@@ -28,6 +43,10 @@ module CalendariumRomanum
|
|
28
43
|
end
|
29
44
|
end
|
30
45
|
|
46
|
+
# Retrieve solemnity for the specified day
|
47
|
+
#
|
48
|
+
# @param date [Date]
|
49
|
+
# @return [Celebration, nil]
|
31
50
|
def get(date)
|
32
51
|
@transferred[date]
|
33
52
|
end
|
@@ -1,12 +1,19 @@
|
|
1
1
|
module CalendariumRomanum
|
2
2
|
|
3
|
+
# General utilities, not tied to the business domain
|
4
|
+
# of liturgical calendar computation.
|
3
5
|
module Util
|
4
6
|
|
5
7
|
# Abstract superclass for date enumerators.
|
8
|
+
# @abstract
|
6
9
|
class DateEnumerator
|
7
10
|
include Enumerable
|
8
11
|
|
12
|
+
# @yield [Date]
|
13
|
+
# @return [void, Enumerator]
|
9
14
|
def each
|
15
|
+
return to_enum(__method__) unless block_given?
|
16
|
+
|
10
17
|
d = @start
|
11
18
|
begin
|
12
19
|
yield d
|
@@ -14,14 +21,16 @@ module CalendariumRomanum
|
|
14
21
|
end until enumeration_over? d
|
15
22
|
end
|
16
23
|
|
24
|
+
# @param date [Date]
|
25
|
+
# @return [Boolean]
|
17
26
|
def enumeration_over?(date)
|
18
27
|
@start.send(@prop) != date.send(@prop)
|
19
28
|
end
|
20
29
|
|
21
|
-
|
30
|
+
alias each_day each
|
22
31
|
end
|
23
32
|
|
24
|
-
#
|
33
|
+
# Enumerates days of a year
|
25
34
|
class Year < DateEnumerator
|
26
35
|
def initialize(year)
|
27
36
|
@start = Date.new year, 1, 1
|
@@ -29,12 +38,36 @@ module CalendariumRomanum
|
|
29
38
|
end
|
30
39
|
end
|
31
40
|
|
32
|
-
#
|
41
|
+
# Enumerates days of a month
|
33
42
|
class Month < DateEnumerator
|
34
43
|
def initialize(year, month)
|
35
44
|
@start = Date.new year, month, 1
|
36
45
|
@prop = :month
|
37
46
|
end
|
38
47
|
end
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
class DateParser
|
51
|
+
def initialize(date_str)
|
52
|
+
if date_str =~ /((\d{4})(\/|-)?(\d{0,2})(\/|-)?(\d{0,2}))\z/ # Accepts YYYY-MM-DD, YYYY/MM/DD where both day and month are optional
|
53
|
+
year = Regexp.last_match(2).to_i
|
54
|
+
month = Regexp.last_match(4).to_i
|
55
|
+
day = Regexp.last_match(6).to_i
|
56
|
+
@date_range = if (day == 0) && (month == 0) # Only year is given
|
57
|
+
Year.new(year)
|
58
|
+
elsif day == 0 # Year and month are given
|
59
|
+
Month.new(year, month)
|
60
|
+
else
|
61
|
+
Date.new(year, month, day)..Date.new(year, month, day)
|
62
|
+
end
|
63
|
+
else
|
64
|
+
raise ArgumentError, 'Unparseable date'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [DateEnumerator, Range]
|
69
|
+
attr_reader :date_range
|
70
|
+
end
|
71
|
+
|
39
72
|
end
|
40
73
|
end
|