weekling 1.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.
- data.tar.gz.sig +2 -0
- data/.gitignore +10 -0
- data/.travis.yml +5 -0
- data/.yardopts +5 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +54 -0
- data/HISTORY.md +6 -0
- data/LICENSE.md +15 -0
- data/README.md +397 -0
- data/Rakefile +47 -0
- data/lib/aef/weekling.rb +45 -0
- data/lib/aef/weekling/core_extensions.rb +28 -0
- data/lib/aef/weekling/core_extensions/to_week_and_week_day.rb +41 -0
- data/lib/aef/weekling/core_extensions/to_year.rb +36 -0
- data/lib/aef/weekling/week.rb +373 -0
- data/lib/aef/weekling/week_day.rb +339 -0
- data/lib/aef/weekling/year.rb +251 -0
- data/lib/weekling.rb +33 -0
- data/lib/weekling/bare.rb +24 -0
- data/spec/aef/weekling/core_extensions_spec.rb +81 -0
- data/spec/aef/weekling/week_day_spec.rb +607 -0
- data/spec/aef/weekling/week_spec.rb +596 -0
- data/spec/aef/weekling/year_spec.rb +378 -0
- data/spec/spec_helper.rb +26 -0
- data/weekling.gemspec +55 -0
- metadata +196 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,339 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Weekling.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'aef/weekling'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Weekling
|
24
|
+
|
25
|
+
# Immutable object representing a calendar week day (according to ISO 8601).
|
26
|
+
class WeekDay
|
27
|
+
include Comparable
|
28
|
+
|
29
|
+
# Table to translate symbolic lowercase english day names to day numbers.
|
30
|
+
# @private
|
31
|
+
SYMBOL_TO_INDEX_TABLE = {
|
32
|
+
:monday => 1,
|
33
|
+
:tuesday => 2,
|
34
|
+
:wednesday => 3,
|
35
|
+
:thursday => 4,
|
36
|
+
:friday => 5,
|
37
|
+
:saturday => 6,
|
38
|
+
:sunday => 7
|
39
|
+
}.freeze
|
40
|
+
|
41
|
+
# Regular expression for week-day extraction from strings.
|
42
|
+
# @private
|
43
|
+
PARSE_PATTERN = /(0|-?\d+)-W(0[1-9]|(?:1|2|3|4)\d|5(?:0|1|2|3))-([1-7])/
|
44
|
+
|
45
|
+
class << self
|
46
|
+
# Initializes the current week day.
|
47
|
+
#
|
48
|
+
# @return [Aef::Weekling::WeekDay] the current week day
|
49
|
+
def today
|
50
|
+
today = Date.today
|
51
|
+
|
52
|
+
new(today, ((today.wday - 1) % 7) + 1)
|
53
|
+
end
|
54
|
+
|
55
|
+
alias now today
|
56
|
+
|
57
|
+
# Parses the first week day out of a string.
|
58
|
+
#
|
59
|
+
# @note Looks for patterns like this:
|
60
|
+
# 2011-W03-5
|
61
|
+
# @param [String] string a string containing a week-day representation
|
62
|
+
# @return [Aef::Weekling::WeekDay] the week day parsed from input
|
63
|
+
# @raise [ArgumentError] if pattern cannot be found
|
64
|
+
def parse(string)
|
65
|
+
if sub_matches = PARSE_PATTERN.match(string.to_s)
|
66
|
+
original, year, week_index, day_index = *sub_matches
|
67
|
+
new(year.to_i, week_index.to_i, day_index.to_i)
|
68
|
+
else
|
69
|
+
raise ArgumentError, 'No week day found for parsing'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [Aef::Weekling::Week] the week the day is part of
|
75
|
+
attr_reader :week
|
76
|
+
|
77
|
+
# @return [Integer] the number of the day in its week
|
78
|
+
attr_reader :index
|
79
|
+
|
80
|
+
# @overload initialize(week_day)
|
81
|
+
# Initialize by a week-day-like object.
|
82
|
+
# @param [Aef::Weekling::WeekDay] week_day a week-day-like object
|
83
|
+
#
|
84
|
+
# @overload initialize(date)
|
85
|
+
# Initialize by a date-like object.
|
86
|
+
# @param [Date, DateTime, Time] date a date-like object
|
87
|
+
#
|
88
|
+
# @overload initialize(week, day)
|
89
|
+
# Initialize by week-like-object and a day.
|
90
|
+
# @param [Aef::Weekling::Week] week a week-like object
|
91
|
+
# @param [Integer, Symbol] day either a day number or a lowercase
|
92
|
+
# english day name
|
93
|
+
#
|
94
|
+
# @overload initialize(year, week_index, day)
|
95
|
+
# Initialize by year, week number and day.
|
96
|
+
# @param [Integer, Aef::Weekling::Year] year a year
|
97
|
+
# @param [Integer] week_number a weeks index
|
98
|
+
# @param [Integer, Symbol] day either a day number or a lowercase english day name
|
99
|
+
def initialize(*arguments)
|
100
|
+
case arguments.count
|
101
|
+
when 1
|
102
|
+
object = arguments.first
|
103
|
+
if [:week, :index].all?{|method_name| object.respond_to?(method_name) }
|
104
|
+
@week = object.week.to_week
|
105
|
+
@index = object.index.to_i
|
106
|
+
elsif object.respond_to?(:to_date)
|
107
|
+
date = object.to_date
|
108
|
+
@week = Week.new(date)
|
109
|
+
@index = ((date.wday - 1) % 7) + 1
|
110
|
+
else
|
111
|
+
raise ArgumentError, 'A single argument must either respond to #week and #index or to #to_date'
|
112
|
+
end
|
113
|
+
when 2
|
114
|
+
week, day = *arguments
|
115
|
+
@week = week.to_week
|
116
|
+
if day.respond_to?(:to_i)
|
117
|
+
@index = day.to_i
|
118
|
+
else
|
119
|
+
raise ArgumentError, 'Invalid day symbol' unless @index = SYMBOL_TO_INDEX_TABLE[day.to_sym]
|
120
|
+
end
|
121
|
+
when 3
|
122
|
+
year, week_index, day = *arguments
|
123
|
+
@week = Week.new(year, week_index)
|
124
|
+
if day.respond_to?(:to_i)
|
125
|
+
@index = day.to_i
|
126
|
+
else
|
127
|
+
raise ArgumentError, 'Invalid day symbol' unless @index = SYMBOL_TO_INDEX_TABLE[day.to_sym]
|
128
|
+
end
|
129
|
+
else
|
130
|
+
raise ArgumentError, "wrong number of arguments (#{arguments.count} for 1..3)"
|
131
|
+
end
|
132
|
+
|
133
|
+
raise ArgumentError, 'Index must be in 1..7' unless (1..7).include?(index)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Represents a week-day as String in ISO 8601 format.
|
137
|
+
#
|
138
|
+
# @example Output of friday in 42nd week of 2525
|
139
|
+
# Aef::Weekling::WeekDay.new(2525, 42, 5).to_s
|
140
|
+
# # => "2525-W42-5"
|
141
|
+
#
|
142
|
+
# @return [String] a character representation of the week day
|
143
|
+
def to_s
|
144
|
+
"#{week}-#{index}"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Represents a week-day as String for debugging.
|
148
|
+
#
|
149
|
+
# @example Output of friday in 42nd week of 2525
|
150
|
+
# Aef::Weekling::WeekDay.new(2525, 42, 5)
|
151
|
+
# # => "#<Aef::Weekling::WeekDay: 2525-W42-5>"
|
152
|
+
#
|
153
|
+
# @return [String] a character representation for debugging
|
154
|
+
def inspect
|
155
|
+
"#<#{self.class.name}: #{to_s}>"
|
156
|
+
end
|
157
|
+
|
158
|
+
# @return [Symbol] a symbolic representation of the week day
|
159
|
+
def to_sym
|
160
|
+
SYMBOL_TO_INDEX_TABLE.invert[index]
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns the date of the week-day.
|
164
|
+
#
|
165
|
+
# @return [Date] the date of the week-day
|
166
|
+
def to_date
|
167
|
+
date = Date.new(week.year.to_i, 1, 1)
|
168
|
+
|
169
|
+
days_to_add = 7 * week.index
|
170
|
+
days_to_add -= 7 if date.cweek == 1
|
171
|
+
days_to_add -= ((date.wday - 1) % 7) + 1
|
172
|
+
days_to_add += index
|
173
|
+
|
174
|
+
date + days_to_add
|
175
|
+
end
|
176
|
+
|
177
|
+
# @return [Aef::Weekling::WeekDay] self reference
|
178
|
+
def to_week_day
|
179
|
+
self
|
180
|
+
end
|
181
|
+
|
182
|
+
# @param [Aef::Weekling::WeekDay] other a week-day-like object to be compared
|
183
|
+
# @return [true, false] true if other lies in the same week and has the
|
184
|
+
# same index
|
185
|
+
def ==(other)
|
186
|
+
other_week_day = self.class.new(other)
|
187
|
+
|
188
|
+
week == other_week_day.week and index == other_week_day.index
|
189
|
+
end
|
190
|
+
|
191
|
+
# @param [Aef::Weekling::WeekDay] other a week-day object to be compared
|
192
|
+
# @return [true, false] true if other lies in the same year, has the same
|
193
|
+
# index and is of the same or a descending class
|
194
|
+
def eql?(other)
|
195
|
+
other.is_a?(self.class) and self == other
|
196
|
+
end
|
197
|
+
|
198
|
+
# @return [see Array#hash] identity hash for hash table usage
|
199
|
+
def hash
|
200
|
+
[week, index].hash
|
201
|
+
end
|
202
|
+
|
203
|
+
# Compares the week-day with another to determine its relative position.
|
204
|
+
#
|
205
|
+
# @param [Aef::Weekling::WeekDay] other a week-day-like object to be compared
|
206
|
+
# @return [-1, 0, 1] -1 if other is greater, 0 if other is equal and 1 if
|
207
|
+
# other is lesser than self
|
208
|
+
def <=>(other)
|
209
|
+
other_week_day = self.class.new(other)
|
210
|
+
|
211
|
+
week_comparison = week <=> other_week_day.week
|
212
|
+
|
213
|
+
return index <=> other_week_day.index if week_comparison == 0
|
214
|
+
return week_comparison
|
215
|
+
end
|
216
|
+
|
217
|
+
# Finds the following week-day.
|
218
|
+
#
|
219
|
+
# @example The thursday after some wednesday
|
220
|
+
# some_day = Aef::Weekling::WeekDay.new(2013, 33, 3)
|
221
|
+
# some_day.next
|
222
|
+
# # => #<Aef::Weekling::WeekDay: 2013-W33-4>
|
223
|
+
#
|
224
|
+
# @example The week-day after a year's last week-day
|
225
|
+
# last_week_day_in_year = Aef::Weekling::WeekDay.new(1998, 53, 7)
|
226
|
+
# last_week_day_in_year.next
|
227
|
+
# # => #<Aef::Weekling::WeekDay: 1999-W01-1>
|
228
|
+
#
|
229
|
+
# @return [Aef::Weekling::WeekDay] the following week-day
|
230
|
+
def next
|
231
|
+
if index == 7
|
232
|
+
self.class.new(week.next, 1)
|
233
|
+
else
|
234
|
+
self.class.new(week, index + 1)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
alias succ next
|
239
|
+
# Find the previous week-day
|
240
|
+
#
|
241
|
+
# @example The sunday before some monday
|
242
|
+
# some_week = Aef::Weekling::WeekDay.new(1783, 16, 1)
|
243
|
+
# some_week.previous
|
244
|
+
# # => #<Aef::Weekling::WeekDay: 1783-W15-7>
|
245
|
+
#
|
246
|
+
# @example The week-day before first week-day of a year
|
247
|
+
# first_week_in_year = Aef::Weekling::WeekDay.new(2014, 1, 1)
|
248
|
+
# first_week_in_year.previous
|
249
|
+
# # => #<Aef::Weekling::WeekDay: 2013-W52-7>
|
250
|
+
#
|
251
|
+
# @return [Aef::Weekling::WeekDay] the previous week-day
|
252
|
+
def previous
|
253
|
+
if index == 1
|
254
|
+
self.class.new(week.previous, 7)
|
255
|
+
else
|
256
|
+
self.class.new(week, index - 1)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
alias pred previous
|
261
|
+
|
262
|
+
# Adds days to the week-day.
|
263
|
+
#
|
264
|
+
# @example 28 days after 2007-W01-1
|
265
|
+
# Aef::Weekling::WeekDay.new(2007, 1, 1) + 28
|
266
|
+
# # => #<Aef::Weekling::WeekDay: 2007-W05-1>
|
267
|
+
#
|
268
|
+
# @param [Integer] other number of days to add
|
269
|
+
# @return [Aef::Weekling::WeekDay] the resulting week-day
|
270
|
+
def +(other)
|
271
|
+
result = self
|
272
|
+
number = other.to_i
|
273
|
+
|
274
|
+
number.abs.times do
|
275
|
+
if number < 0
|
276
|
+
result = result.previous
|
277
|
+
else
|
278
|
+
result = result.next
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
result
|
283
|
+
end
|
284
|
+
|
285
|
+
# Subtracts days from the week-day.
|
286
|
+
#
|
287
|
+
# @example 5 days before 2012-W45-3
|
288
|
+
# Aef::Weekling::WeekDay.new(2012, 45, 3) - 5
|
289
|
+
# # => #<Aef::Weekling::WeekDay: 2012-W44-5>
|
290
|
+
#
|
291
|
+
# @param [Integer] other number of days to subtract
|
292
|
+
# @return [Aef::Weekling::WeekDay] the resulting week-day
|
293
|
+
def -(other)
|
294
|
+
self + -other.to_i
|
295
|
+
end
|
296
|
+
|
297
|
+
# @return [true, false] true if week day is monday
|
298
|
+
def monday?
|
299
|
+
to_sym == :monday
|
300
|
+
end
|
301
|
+
|
302
|
+
# @return [true, false] true if week day is tuesday
|
303
|
+
def tuesday?
|
304
|
+
to_sym == :tuesday
|
305
|
+
end
|
306
|
+
|
307
|
+
# @return [true, false] true if week day is wednesday
|
308
|
+
def wednesday?
|
309
|
+
to_sym == :wednesday
|
310
|
+
end
|
311
|
+
|
312
|
+
# @return [true, false] true if week day is thursday
|
313
|
+
def thursday?
|
314
|
+
to_sym == :thursday
|
315
|
+
end
|
316
|
+
|
317
|
+
# @return [true, false] true if week day is friday
|
318
|
+
def friday?
|
319
|
+
to_sym == :friday
|
320
|
+
end
|
321
|
+
|
322
|
+
# @return [true, false] true if week day is saturday
|
323
|
+
def saturday?
|
324
|
+
to_sym == :saturday
|
325
|
+
end
|
326
|
+
|
327
|
+
# @return [true, false] true if week day is sunday
|
328
|
+
def sunday?
|
329
|
+
to_sym == :sunday
|
330
|
+
end
|
331
|
+
|
332
|
+
# @return [true, false] true if week day is saturday or sunday
|
333
|
+
def weekend?
|
334
|
+
saturday? or sunday?
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Weekling.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'aef/weekling'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Weekling
|
24
|
+
|
25
|
+
# Immutable object representing a calendar year (according to ISO 8601).
|
26
|
+
class Year
|
27
|
+
include Comparable
|
28
|
+
|
29
|
+
# Regular expression for Year extraction from strings.
|
30
|
+
# @private
|
31
|
+
PARSE_PATTERN = /(0|-?\d+)/
|
32
|
+
|
33
|
+
class << self
|
34
|
+
# Initializes the current year.
|
35
|
+
#
|
36
|
+
# @return [Aef::Weekling::Year] the current year
|
37
|
+
def today
|
38
|
+
today = Date.today
|
39
|
+
|
40
|
+
new(today.year)
|
41
|
+
end
|
42
|
+
|
43
|
+
alias now today
|
44
|
+
|
45
|
+
# Parses the first year out of a string.
|
46
|
+
#
|
47
|
+
# @note Looks for patterns like this:
|
48
|
+
# 2011
|
49
|
+
# @param [String] string a string containing a year representation
|
50
|
+
# @return [Aef::Weekling::Year] the year parsed from input
|
51
|
+
# @raise [ArgumentError] if pattern cannot be found
|
52
|
+
def parse(string)
|
53
|
+
if sub_matches = PARSE_PATTERN.match(string.to_s)
|
54
|
+
original, year = *sub_matches
|
55
|
+
new(year.to_i)
|
56
|
+
else
|
57
|
+
raise ArgumentError, 'No year found for parsing'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Integer] the number of the year
|
63
|
+
attr_reader :index
|
64
|
+
|
65
|
+
# @overload initialize(index)
|
66
|
+
# Initialize by number.
|
67
|
+
# @param [Integer] index the year's number
|
68
|
+
#
|
69
|
+
# @overload initialize(date)
|
70
|
+
# Initialize by a date-like object.
|
71
|
+
# @param [Date, DateTime, Time] date a date-like object
|
72
|
+
def initialize(index_or_date)
|
73
|
+
if index_or_date.respond_to?(:to_date)
|
74
|
+
date = index_or_date.to_date
|
75
|
+
@index = date.year
|
76
|
+
elsif index_or_date.respond_to?(:to_i)
|
77
|
+
@index = index_or_date.to_i
|
78
|
+
else
|
79
|
+
raise ArgumentError, 'A single argument must either respond to #to_date or to #to_i'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Represents the year as Integer.
|
84
|
+
#
|
85
|
+
# @return [Integer] the year's number
|
86
|
+
def to_i
|
87
|
+
@index
|
88
|
+
end
|
89
|
+
|
90
|
+
# Represents the year as String in ISO 8601 format.
|
91
|
+
#
|
92
|
+
# @example Output of the year 2012
|
93
|
+
# Aef::Weekling::Year.new(2012).to_s
|
94
|
+
# # => "2012"
|
95
|
+
#
|
96
|
+
# @return [String] a character representation of the year
|
97
|
+
def to_s
|
98
|
+
@index.to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
# Represents a week as String for debugging.
|
102
|
+
#
|
103
|
+
# @example Output of the year 2012
|
104
|
+
# Aef::Weekling::Year.new(2012).inspect
|
105
|
+
# # => "<#Aef::Weekling::Year: 2012>"
|
106
|
+
def inspect
|
107
|
+
"#<#{self.class.name}: #{to_s}>"
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [Aef::Weekling::Year] self reference
|
111
|
+
def to_year
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
# @param [Aef::Weekling::Year] other a year-like object to be compared
|
116
|
+
# @return [true, false] true if other has the same index
|
117
|
+
def ==(other)
|
118
|
+
other_year = self.class.new(other)
|
119
|
+
|
120
|
+
self.index == other_year.index
|
121
|
+
end
|
122
|
+
|
123
|
+
# @param [Aef::Weekling::Year] other a year object to be compared
|
124
|
+
# @return [true, false] true if other has the same index and is of the
|
125
|
+
# same or descending class
|
126
|
+
def eql?(other)
|
127
|
+
self == other and other.is_a?(self.class)
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [see Integer#hash] identity hash for hash table usage
|
131
|
+
def hash
|
132
|
+
@index.hash
|
133
|
+
end
|
134
|
+
|
135
|
+
# Compares the year with another to determine its relative position.
|
136
|
+
#
|
137
|
+
# @param [Aef::Weekling::Year] other a year-like object to be compared
|
138
|
+
# @return [-1, 0, 1] -1 if other is greater, 0 if other is equal and 1 if
|
139
|
+
# other is lesser than self
|
140
|
+
def <=>(other)
|
141
|
+
other_year = other.to_year
|
142
|
+
|
143
|
+
self.index <=> other_year.index
|
144
|
+
end
|
145
|
+
|
146
|
+
# Finds the following year.
|
147
|
+
#
|
148
|
+
# @example The year after some other year
|
149
|
+
# some_year = Aef::Weekling::Year.new(2012)
|
150
|
+
# some_year.next
|
151
|
+
# # => #<Aef::Weekling::Year: 2013>
|
152
|
+
#
|
153
|
+
# @return [Aef::Weekling::Year] the following year
|
154
|
+
def next
|
155
|
+
self.class.new(@index + 1)
|
156
|
+
end
|
157
|
+
|
158
|
+
alias succ next
|
159
|
+
|
160
|
+
# Finds the previous year.
|
161
|
+
#
|
162
|
+
# @example The year before some other year
|
163
|
+
# some_year = Aef::Weekling::Year.new(2012)
|
164
|
+
# some_year.previous
|
165
|
+
# # => #<Aef::Weekling::Year: 2011>
|
166
|
+
#
|
167
|
+
# @return [Aef::Weekling::Year] the previous year
|
168
|
+
def previous
|
169
|
+
self.class.new(@index - 1)
|
170
|
+
end
|
171
|
+
|
172
|
+
alias pred previous
|
173
|
+
|
174
|
+
# Adds years to the year.
|
175
|
+
#
|
176
|
+
# @example 3 year after 2000
|
177
|
+
# Aef::Weekling::Year.new(2000) + 3
|
178
|
+
# # => #<Aef::Weekling::Year: 2003>
|
179
|
+
#
|
180
|
+
# @param [Integer] other number of years to add
|
181
|
+
# @return [Aef::Weekling::Year] the resulting year
|
182
|
+
def +(other)
|
183
|
+
self.class.new(@index + other.to_i)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Subtracts years from the year.
|
187
|
+
#
|
188
|
+
# @example 3 before 2000
|
189
|
+
# Aef::Weekling::Year.new(2000) - 3
|
190
|
+
# # => #<Aef::Weekling::Year: 1997>
|
191
|
+
#
|
192
|
+
# @param [Integer] other number of years to subtract
|
193
|
+
# @return [Aef::Weekling::Year] the resulting year
|
194
|
+
def -(other)
|
195
|
+
self.class.new(@index - other.to_i)
|
196
|
+
end
|
197
|
+
|
198
|
+
# States if the year's index is odd.
|
199
|
+
#
|
200
|
+
# @return [true, false] true if the year is odd
|
201
|
+
def odd?
|
202
|
+
@index.odd?
|
203
|
+
end
|
204
|
+
|
205
|
+
# States if the year's index is even.
|
206
|
+
#
|
207
|
+
# @return [true, false] true if the year is even
|
208
|
+
def even?
|
209
|
+
@index.even?
|
210
|
+
end
|
211
|
+
|
212
|
+
# States if the year is a leap year.
|
213
|
+
#
|
214
|
+
# @return [true, false] true is the year is a leap year
|
215
|
+
def leap?
|
216
|
+
Date.leap?(to_i)
|
217
|
+
end
|
218
|
+
|
219
|
+
# Calculates the amount of weeks in year.
|
220
|
+
#
|
221
|
+
# @example Acquire the amount of weeks for 2015
|
222
|
+
# Aef::Weekling::Year.new(2015).week_count
|
223
|
+
# # => 53
|
224
|
+
#
|
225
|
+
# @return [Integer] the amount of weeks
|
226
|
+
def week_count
|
227
|
+
date = Date.new(index, 12, 31)
|
228
|
+
|
229
|
+
date = date - 7 if date.cweek == 1
|
230
|
+
|
231
|
+
date.cweek
|
232
|
+
end
|
233
|
+
|
234
|
+
# Finds a week in the year.
|
235
|
+
#
|
236
|
+
# @param [Integer] index the week's index
|
237
|
+
# @return [Aef::Weekling::Week] the week in year with the given index
|
238
|
+
def week(index)
|
239
|
+
Week.new(self, index.to_i)
|
240
|
+
end
|
241
|
+
|
242
|
+
# Returns a range of all weeks in year.
|
243
|
+
#
|
244
|
+
# @return [Range<Aef::Weekling::Week>] all weeks in year
|
245
|
+
def weeks
|
246
|
+
week(1)..week(week_count)
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|