timeboss 0.0.10 → 0.2.2

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.
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+ module TimeBoss
3
+ class Calendar
4
+ module Support
5
+ module Translatable
6
+ PERIODS = %w[day week month quarter half year]
7
+
8
+ PERIODS.each do |period|
9
+ periods = period.pluralize
10
+
11
+ define_method(periods) { calendar.send("#{periods}_for", self) }
12
+
13
+ define_method(period) do
14
+ entries = send(periods)
15
+ return nil unless entries.length == 1
16
+ entries.first
17
+ end
18
+ end
19
+
20
+ #
21
+ # i hate this
22
+ #
23
+
24
+ ### Days
25
+
26
+ # @!method days
27
+ # Get a list of days that fall within this unit.
28
+ # @return [Array<Calendar::Day>]
29
+
30
+ # @!method day
31
+ # Get the day this unit represents.
32
+ # Returns nil if no single day can be identified.
33
+ # @return [Array<Calendar::Day>, nil]
34
+
35
+ ### Weeks
36
+
37
+ # @!method weeks
38
+ # Get a list of weeks that fall within this unit.
39
+ # @return [Array<Calendar::Week>]
40
+
41
+ # @!method week
42
+ # Get the week this unit represents.
43
+ # Returns nil if no single week can be identified.
44
+ # @return [Array<Calendar::Week>, nil]
45
+
46
+ ### Months
47
+
48
+ # @!method months
49
+ # Get a list of months that fall within this unit.
50
+ # @return [Array<Calendar::Month>]
51
+
52
+ # @!method month
53
+ # Get the month this unit represents.
54
+ # Returns nil if no single month can be identified.
55
+ # @return [Array<Calendar::Month>, nil]
56
+
57
+ ### Quarters
58
+
59
+ # @!method quarters
60
+ # Get a list of quarters that fall within this unit.
61
+ # @return [Array<Calendar::Quarter>]
62
+
63
+ # @!method quarter
64
+ # Get the quarter this unit represents.
65
+ # Returns nil if no single quarter can be identified.
66
+ # @return [Array<Calendar::Quarter>, nil]
67
+
68
+ ### Halves
69
+
70
+ # @!method halves
71
+ # Get a list of halves that fall within this unit.
72
+ # @return [Array<Calendar::Half>]
73
+
74
+ # @!method half
75
+ # Get the half this unit represents.
76
+ # Returns nil if no single half can be identified.
77
+ # @return [Array<Calendar::Half>, nil]
78
+
79
+ ### Years
80
+
81
+ # @!method years
82
+ # Get a list of years that fall within this unit.
83
+ # @return [Array<Calendar::Year>]
84
+
85
+ # @!method year
86
+ # Get the year this unit represents.
87
+ # Returns nil if no single year can be identified.
88
+ # @return [Array<Calendar::Year>, nil]
89
+ end
90
+ end
91
+ end
92
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require_relative './navigable'
3
+ require_relative './translatable'
3
4
  require_relative './shiftable'
4
5
  require_relative './formatter'
5
6
 
@@ -8,9 +9,12 @@ module TimeBoss
8
9
  module Support
9
10
  class Unit
10
11
  include Navigable
12
+ include Translatable
11
13
  include Shiftable
12
14
  attr_reader :calendar, :start_date, :end_date
13
15
 
16
+ UnsupportedUnitError = Class.new(StandardError)
17
+
14
18
  def self.type
15
19
  self.name.demodulize.underscore
16
20
  end
@@ -21,22 +25,37 @@ module TimeBoss
21
25
  @end_date = end_date
22
26
  end
23
27
 
28
+ # Is the specified unit equal to this one, based on its unit type and date range?
29
+ # @param entry [Unit] the unit to compare
30
+ # @return [Boolean] true when periods are equal
24
31
  def ==(entry)
25
32
  self.class == entry.class && self.start_date == entry.start_date && self.end_date == entry.end_date
26
33
  end
27
34
 
35
+ # Format this period based on specified granularities.
36
+ # @param periods [Array<Symbol, String>] the periods to include (`half, week`, or `quarter`)
37
+ # @return [String] (e.g. "2020H2W7" or "2020Q3")
28
38
  def format(*periods)
29
39
  Formatter.new(self, periods.presence || Formatter::PERIODS).to_s
30
40
  end
31
41
 
42
+ # Starting from this unit of time, build a period extending through the specified time unit.
43
+ # @param unit [Unit] the period to extend through
44
+ # @return [Period]
32
45
  def thru(unit)
33
46
  Period.new(calendar, self, unit)
34
47
  end
35
48
 
49
+ # Does this period cover the current date?
50
+ # @return [Boolean]
36
51
  def current?
37
52
  Date.today.between?(start_date, end_date)
38
53
  end
39
54
 
55
+ # Return the unit relative to this one by the specified offset.
56
+ # Offset values can be positive or negative.
57
+ # @param value [Integer]
58
+ # @return [Unit]
40
59
  def offset(value)
41
60
  method = value.negative? ? :previous : :next
42
61
  base = self
@@ -44,14 +63,22 @@ module TimeBoss
44
63
  base
45
64
  end
46
65
 
66
+ # Move some number of units forward from this unit.
67
+ # @param value [Integer]
68
+ # @return [Unit]
47
69
  def +(value)
48
70
  offset(value)
49
71
  end
50
72
 
73
+ # Move some number of units backward from this unit.
74
+ # @param value [Integer]
75
+ # @return [Unit]
51
76
  def -(value)
52
77
  offset(-value)
53
78
  end
54
79
 
80
+ # Express this period as a date range.
81
+ # @return [Range<Date, Date>]
55
82
  def to_range
56
83
  @_to_range ||= start_date .. end_date
57
84
  end
@@ -1,62 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
3
+ %w[absolute relative].each { |f| require_relative "./waypoints/#{f}" }
4
+
2
5
  module TimeBoss
3
6
  class Calendar
4
7
  module Waypoints
5
- %i[month quarter half year].each do |type|
6
- klass = TimeBoss::Calendar.const_get(type.to_s.classify)
7
- size = klass.const_get("NUM_MONTHS")
8
-
9
- define_method type do |year_index, index = 1|
10
- month = (index * size) - size + 1
11
- months = (month .. month + size - 1).map { |i| basis.new(year_index, i) }
12
- klass.new(self, year_index, index, months.first.start_date, months.last.end_date)
13
- end
14
-
15
- define_method "#{type}_for" do |date|
16
- window = send(type, date.year - 1, 1)
17
- while true
18
- break window if window.to_range.include?(date)
19
- window = window.next
20
- end
21
- end
22
- end
23
-
24
- def week(year_index, index)
25
- year(year_index).weeks[index - 1]
26
- end
27
-
28
- def week_for(date)
29
- year_for(date).weeks.find { |w| w.to_range.include?(date) }
30
- end
31
-
32
- def day(year_index, index)
33
- year(year_index).days[index - 1]
34
- end
35
-
36
- def day_for(date)
37
- Day.new(self, date)
38
- end
39
-
40
- %i[day week month quarter half year].each do |type|
41
- types = type.to_s.pluralize
42
-
43
- define_method("this_#{type}") { send("#{type}_for", Date.today) }
44
- define_method("last_#{type}") { send("this_#{type}").previous }
45
- define_method("next_#{type}") { send("this_#{type}").next }
46
-
47
- define_method("#{types}_for") { |p| send("#{type}_for", p.start_date).until(p.end_date) }
48
-
49
- define_method("#{types}_back") { |q| send("this_#{type}").previous(q) }
50
- define_method("#{types}_ago") { |q| send("this_#{type}").ago(q) }
51
-
52
- define_method("#{types}_forward") { |q| send("this_#{type}").next(q) }
53
- define_method("#{types}_hence") { |q| send("this_#{type}").hence(q) }
54
- alias_method types.to_sym, "#{types}_forward".to_sym
55
- end
56
-
57
- alias_method :yesterday, :last_day
58
- alias_method :today, :this_day
59
- alias_method :tomorrow, :next_day
8
+ include Absolute
9
+ include Relative
60
10
  end
61
11
  end
62
12
  end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+ module TimeBoss
3
+ class Calendar
4
+ module Waypoints
5
+ module Absolute
6
+ %i[month quarter half year].each do |type|
7
+ klass = TimeBoss::Calendar.const_get(type.to_s.classify)
8
+ size = klass.const_get("NUM_MONTHS")
9
+
10
+ define_method type do |year_index, index = 1|
11
+ month = (index * size) - size + 1
12
+ months = (month .. month + size - 1).map { |i| basis.new(year_index, i) }
13
+ klass.new(self, year_index, index, months.first.start_date, months.last.end_date)
14
+ end
15
+
16
+ define_method "#{type}_for" do |date|
17
+ window = send(type, date.year - 1, 1)
18
+ while true
19
+ break window if window.to_range.include?(date)
20
+ window = window.next
21
+ end
22
+ end
23
+ end
24
+
25
+ # Get the specified week by index within the specified year.
26
+ # @param year_index [Integer] the year to examine
27
+ # @param index [Integer] the index of the week within the year
28
+ # @return [Calendar::Week]
29
+ def week(year_index, index)
30
+ year(year_index).weeks[index - 1]
31
+ end
32
+
33
+ # Get the week that contains the specified date.
34
+ # @param date [Date] the date for which to locate the calendar week
35
+ # @return [Calendar::Week]
36
+ def week_for(date)
37
+ year_for(date).weeks.find { |w| w.to_range.include?(date) }
38
+ end
39
+
40
+ # Get the specified day by index within the specified year.
41
+ # @param year_index [Integer] the year to examine
42
+ # @param index [Integer] the index of the day within the year
43
+ # @return [Calendar::Day]
44
+ def day(year_index, index)
45
+ year(year_index).days[index - 1]
46
+ end
47
+
48
+ # Get the day that contains the specified date.
49
+ # @param date [Date] the date for which to locate the calendar day
50
+ # @return [Calendar::Day]
51
+ def day_for(date)
52
+ Day.new(self, date)
53
+ end
54
+
55
+ #
56
+ # i hate this
57
+ #
58
+
59
+ ### Month
60
+
61
+ # @!method month
62
+ # Get the specified month by index within the specified year
63
+ # @param year_index [Integer] the year to examine
64
+ # @param index [Integer] the index of the month within the year
65
+ # @return [Calendar::Month]
66
+
67
+ # @!method month_for
68
+ # Get the month that contains the specified date.
69
+ # @param date [Date] the date for which to locate the calendar month
70
+ # @return [Calendar::Month]
71
+
72
+ ### Quarter
73
+
74
+ # @!method quarter
75
+ # Get the specified quarter by index within the specified year
76
+ # @param year_index [Integer] the year to examine
77
+ # @param index [Integer] the index of the quarter within the year
78
+ # @return [Calendar::Quarter]
79
+
80
+ # @!method quarter_for
81
+ # Get the quarter that contains the specified date.
82
+ # @param date [Date] the date for which to locate the calendar quarter
83
+ # @return [Calendar::Quarter]
84
+
85
+ ### Half
86
+
87
+ # @!method half
88
+ # Get the specified half by index within the specified year
89
+ # @param year_index [Integer] the year to examine
90
+ # @param index [Integer] the index of the half within the year
91
+ # @return [Calendar::Half]
92
+
93
+ # @!method half_for
94
+ # Get the half that contains the specified date.
95
+ # @param date [Date] the date for which to locate the calendar half
96
+ # @return [Calendar::Half]
97
+
98
+ ### Year
99
+
100
+ # @!method year
101
+ # Get the specified year by index within the specified year
102
+ # @param year_index [Integer] the year to examine
103
+ # @param index [Integer] the index of the year within the year
104
+ # @return [Calendar::Year]
105
+
106
+ # @!method year_for
107
+ # Get the year that contains the specified date.
108
+ # @param date [Date] the date for which to locate the calendar year
109
+ # @return [Calendar::Year]
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,267 @@
1
+ # frozen_string_literal: true
2
+ module TimeBoss
3
+ class Calendar
4
+ module Waypoints
5
+ module Relative
6
+ %i[day week month quarter half year].each do |type|
7
+ types = type.to_s.pluralize
8
+
9
+ define_method("this_#{type}") { send("#{type}_for", Date.today) }
10
+ define_method("last_#{type}") { send("this_#{type}").previous }
11
+ define_method("next_#{type}") { send("this_#{type}").next }
12
+
13
+ define_method("#{types}_for") { |p| send("#{type}_for", p.start_date).until(p.end_date) }
14
+
15
+ define_method("#{types}_back") { |q| send("this_#{type}").previous(q) }
16
+ define_method("#{types}_ago") { |q| send("this_#{type}").ago(q) }
17
+
18
+ define_method("#{types}_forward") { |q| send("this_#{type}").next(q) }
19
+ define_method("#{types}_ahead") { |q| send("this_#{type}").ahead(q) }
20
+ alias_method types.to_sym, "#{types}_forward".to_sym
21
+ end
22
+
23
+ alias_method :yesterday, :last_day
24
+ alias_method :today, :this_day
25
+ alias_method :tomorrow, :next_day
26
+
27
+ #
28
+ # i hate this
29
+ #
30
+
31
+ ### Days
32
+
33
+ # @!method this_day
34
+ # Get the current day within the active calendar.
35
+ # @return [Calendar::Day]
36
+
37
+ # @!method last_day
38
+ # Get the previous day within the active calendar.
39
+ # @return [Calendar::Day]
40
+
41
+ # @!method next_day
42
+ # Get the next day within the active calendar.
43
+ # @return [Calendar::Day]
44
+
45
+ # @!method days_for
46
+ # Get a list of days within the specified period unit.
47
+ # @param period [Calendar::Support::Unit] the containing period unit
48
+ # @return [Array<Calendar::Day>]
49
+
50
+ # @!method days_back
51
+ # Get a quantity of days back from today.
52
+ # @param quantity [Integer] the number of days requested
53
+ # @return [Array<Calendar::Day>]
54
+
55
+ # @!method days_ago
56
+ # Get the day that occurred the specified number of days ago.
57
+ # @param quantity [Integer] the number of days before today
58
+ # @return [Calendar::Day]
59
+
60
+ # @!method days_forward
61
+ # Get a quantity of days forward from today.
62
+ # @param quantity [Integer] the number of days requested
63
+ # @return [Array<Calendar::Day>]
64
+
65
+ # @!method days_ahead
66
+ # Get the day that occurred the specified number of days ahead.
67
+ # @param quantity [Integer] the number of days after today
68
+ # @return [Calendar::Day]
69
+
70
+ ### Weeks
71
+
72
+ # @!method this_week
73
+ # Get the current week within the active calendar.
74
+ # @return [Calendar::Week]
75
+
76
+ # @!method last_week
77
+ # Get the previous week within the active calendar.
78
+ # @return [Calendar::Week]
79
+
80
+ # @!method next_week
81
+ # Get the next week within the active calendar.
82
+ # @return [Calendar::Week]
83
+
84
+ # @!method weeks_for
85
+ # Get a list of weeks within the specified period unit.
86
+ # @param period [Calendar::Support::Unit] the containing period unit
87
+ # @return [Array<Calendar::Week>]
88
+
89
+ # @!method weeks_back
90
+ # Get a quantity of weeks back from this week.
91
+ # @param quantity [Integer] the number of weeks requested
92
+ # @return [Array<Calendar::Week>]
93
+
94
+ # @!method weeks_ago
95
+ # Get the week that occurred the specified number of weeks ago.
96
+ # @param quantity [Integer] the number of weeks before this week
97
+ # @return [Calendar::Week]
98
+
99
+ # @!method weeks_forward
100
+ # Get a quantity of weeks forward from this week.
101
+ # @param quantity [Integer] the number of weeks requested
102
+ # @return [Array<Calendar::Week>]
103
+
104
+ # @!method weeks_ahead
105
+ # Get the week that occurred the specified number of weeks ahead.
106
+ # @param quantity [Integer] the number of weeks after this week
107
+ # @return [Calendar::Week]
108
+
109
+ ### Months
110
+
111
+ # @!method this_month
112
+ # Get the current month within the active calendar.
113
+ # @return [Calendar::Month]
114
+
115
+ # @!method last_month
116
+ # Get the previous month within the active calendar.
117
+ # @return [Calendar::Month]
118
+
119
+ # @!method next_month
120
+ # Get the next month within the active calendar.
121
+ # @return [Calendar::Month]
122
+
123
+ # @!method months_for
124
+ # Get a list of months within the specified period unit.
125
+ # @param period [Calendar::Support::Unit] the containing period unit
126
+ # @return [Array<Calendar::Month>]
127
+
128
+ # @!method months_back
129
+ # Get a quantity of months back from this month.
130
+ # @param quantity [Integer] the number of months requested
131
+ # @return [Array<Calendar::Month>]
132
+
133
+ # @!method months_ago
134
+ # Get the month that occurred the specified number of months ago.
135
+ # @param quantity [Integer] the number of months before this month
136
+ # @return [Calendar::Month]
137
+
138
+ # @!method months_forward
139
+ # Get a quantity of months forward from this month.
140
+ # @param quantity [Integer] the number of months requested
141
+ # @return [Array<Calendar::Month>]
142
+
143
+ # @!method months_ahead
144
+ # Get the month that occurred the specified number of months ahead.
145
+ # @param quantity [Integer] the number of months after this month
146
+ # @return [Calendar::Month]
147
+
148
+ ### Quarters
149
+
150
+ # @!method this_quarter
151
+ # Get the current quarter within the active calendar.
152
+ # @return [Calendar::Quarter]
153
+
154
+ # @!method last_quarter
155
+ # Get the previous quarter within the active calendar.
156
+ # @return [Calendar::Quarter]
157
+
158
+ # @!method next_quarter
159
+ # Get the next quarter within the active calendar.
160
+ # @return [Calendar::Quarter]
161
+
162
+ # @!method quarters_for
163
+ # Get a list of quarters within the specified period unit.
164
+ # @param period [Calendar::Support::Unit] the containing period unit
165
+ # @return [Array<Calendar::Quarter>]
166
+
167
+ # @!method quarters_back
168
+ # Get a quantity of quarters back from this quarter.
169
+ # @param quantity [Integer] the number of quarters requested
170
+ # @return [Array<Calendar::Quarter>]
171
+
172
+ # @!method quarters_ago
173
+ # Get the quarter that occurred the specified number of quarters ago.
174
+ # @param quantity [Integer] the number of quarters before this quarter
175
+ # @return [Calendar::Quarter]
176
+
177
+ # @!method quarters_forward
178
+ # Get a quantity of quarters forward from this quarter.
179
+ # @param quantity [Integer] the number of quarters requested
180
+ # @return [Array<Calendar::Quarter>]
181
+
182
+ # @!method quarters_ahead
183
+ # Get the quarter that occurred the specified number of days ahead.
184
+ # @param quantity [Integer] the number of quarters after this quarter
185
+ # @return [Calendar::Quarter]
186
+
187
+ ### Halves
188
+
189
+ # @!method this_half
190
+ # Get the current half within the active calendar.
191
+ # @return [Calendar::Half]
192
+
193
+ # @!method last_half
194
+ # Get the previous half within the active calendar.
195
+ # @return [Calendar::Half]
196
+
197
+ # @!method next_half
198
+ # Get the next half within the active calendar.
199
+ # @return [Calendar::Half]
200
+
201
+ # @!method halves_for
202
+ # Get a list of halves within the specified period unit.
203
+ # @param period [Calendar::Support::Unit] the containing period unit
204
+ # @return [Array<Calendar::Half>]
205
+
206
+ # @!method halves_back
207
+ # Get a quantity of halves back from this half.
208
+ # @param quantity [Integer] the number of halves requested
209
+ # @return [Array<Calendar::Half>]
210
+
211
+ # @!method halves_ago
212
+ # Get the half that occurred the specified number of halves ago.
213
+ # @param quantity [Integer] the number of halves before this half
214
+ # @return [Calendar::Half]
215
+
216
+ # @!method halves_forward
217
+ # Get a quantity of halves forward from this half.
218
+ # @param quantity [Integer] the number of halves requested
219
+ # @return [Array<Calendar::Half>]
220
+
221
+ # @!method halves_ahead
222
+ # Get the half that occurred the specified number of halves ahead.
223
+ # @param quantity [Integer] the number of halves after this half
224
+ # @return [Calendar::Half]
225
+
226
+ ### Years
227
+
228
+ # @!method this_year
229
+ # Get the current year within the active calendar.
230
+ # @return [Calendar::Year]
231
+
232
+ # @!method last_year
233
+ # Get the previous year within the active calendar.
234
+ # @return [Calendar::Year]
235
+
236
+ # @!method next_year
237
+ # Get the next year within the active calendar.
238
+ # @return [Calendar::Year]
239
+
240
+ # @!method years_for
241
+ # Get a list of years within the specified period unit.
242
+ # @param period [Calendar::Support::Unit] the containing period unit
243
+ # @return [Array<Calendar::Year>]
244
+
245
+ # @!method years_back
246
+ # Get a quantity of years back from this year.
247
+ # @param quantity [Integer] the number of years requested
248
+ # @return [Array<Calendar::Year>]
249
+
250
+ # @!method years_ago
251
+ # Get the year that occurred the specified number of years ago.
252
+ # @param quantity [Integer] the number of years before this year
253
+ # @return [Calendar::Year]
254
+
255
+ # @!method years_forward
256
+ # Get a quantity of years forward from this year.
257
+ # @param quantity [Integer] the number of years requested
258
+ # @return [Array<Calendar::Year>]
259
+
260
+ # @!method years_ahead
261
+ # Get the year that occurred the specified number of years ahead.
262
+ # @param quantity [Integer] the number of years after this year
263
+ # @return [Calendar::Year]
264
+ end
265
+ end
266
+ end
267
+ end