periodoxical 0.9.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1028e4261c9759e49e7446a1ff506fcb4d3b789b4bdd1ef40dbec0bd8df18ae8
4
- data.tar.gz: c7dece06fabe86ede77b98203bea7716d0d1e039393f1e6e693c8a232615ef01
3
+ metadata.gz: 2b67da50d1bba17e1d25babaa937440ccad41bf152d1df8d3adb50ff8c9199b3
4
+ data.tar.gz: 954c91d5da06a9d4955fdb35576b11f1e209a8ab152825c3f09657e891787a5d
5
5
  SHA512:
6
- metadata.gz: '08dc98ece1a24ed33564c60f32c31fcf76defddbab51fbf2c0c3df04b296759767fc1dde8a4ed744a24b700fe812ce97bcdc06c052c382e61872c55426116258'
7
- data.tar.gz: c8edb8ea410b88c5888edda103752c27c149e4e06421b74fb7c4a29ed0f09ae32726536ed495702156b8e6e054da0a5140e1a3487bbbac4468abb94ed7cfb79f
6
+ metadata.gz: ab9f0eb8538ea18407171b2d9dc435935821370f3f3d229f59d718e3e11f3eba6b6f926129274f33c5100b22a70d937ba6f9693d714f52abaf0f2a7be4965d28
7
+ data.tar.gz: 64503a74a1879ae8d0cda934ad511530ff6c22e5f1aeb9fe331f0dda99ccf8d7b81c735e2d10a9c6ce468010ea64674c1d8bc86a24fa8f18aa5382cfd29facdd
data/CODE_OF_CONDUCT.md CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
55
55
  ## Enforcement
56
56
 
57
57
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at steven@fountain.com. All
58
+ reported by contacting the project team at stevenJLi@gmail.com. All
59
59
  complaints will be reviewed and investigated and will result in a response that
60
60
  is deemed necessary and appropriate to the circumstances. The project team is
61
61
  obligated to maintain confidentiality with regard to the reporter of an incident.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- periodoxical (0.9.3)
4
+ periodoxical (1.1.0)
5
5
  tzinfo (~> 2.0, >= 2.0.0)
6
6
  week_of_month (= 1.2.6)
7
7
 
data/README.md CHANGED
@@ -29,7 +29,7 @@ Or install it yourself as:
29
29
 
30
30
  ## Usage
31
31
 
32
- ### Example 1
32
+ ### Basic Example
33
33
  As a Ruby dev, I want to generate all the datetime blocks of **9:00AM - 10:30AM** for all days from **May 23, 2024** to **May 26, 2024** inclusive.
34
34
 
35
35
  ```rb
@@ -41,8 +41,8 @@ Periodoxical.generate(
41
41
  end_time: '10:30AM'
42
42
  },
43
43
  ],
44
- start_date: '2024-05-23',
45
- end_date: '2024-05-27',
44
+ starting_from: '2024-05-23',
45
+ ending_at: '2024-05-26',
46
46
  )
47
47
  #=>
48
48
  [
@@ -65,8 +65,33 @@ Periodoxical.generate(
65
65
  ]
66
66
  ```
67
67
 
68
- ### Example 2 - specify days of the week
69
- As a Ruby dev, I want to generate all the datetime blocks of **9:00AM - 10:30AM** and **2:00PM - 2:30PM**, on **Mondays**, **Wednesdays**, and **Thursdays**, between the dates of **May 23, 2024** and **June 12, 2024**, inclusive. This can be represented visually as:
68
+ The `starting_from` and `ending_at` params can also accept datetimes in ISO 8601 format. This example generate all the datetime blocks of **9:00AM - 10:30AM** but starting from **May 23, 2024 at 9:30AM**.
69
+
70
+ ```rb
71
+ Periodoxical.generate(
72
+ time_zone: 'America/Los_Angeles',
73
+ time_blocks: [
74
+ {
75
+ start_time: '9:00AM',
76
+ end_time: '10:30AM'
77
+ },
78
+ ],
79
+ starting_from: '2024-05-23T09:30:00-07:00', # can be string in iso8601 format
80
+ ending_at: DateTime.parse('2024-05-26T17:00:00-07:00'), # or an instance of DateTime
81
+ )
82
+ #=> [
83
+ # 2024-05-23 was skipped because the 9AM time block was before
84
+ # the `starting_from` of '2024-05-23T09:30:00-07:00'
85
+ {
86
+ start_time: #<DateTime: 2024-05-24T09:00:00-0700>,
87
+ end_time: #<DateTime: 2024-05-24T10:30:00-0700>,
88
+ },
89
+ ...
90
+ ]
91
+ ```
92
+
93
+ ### Specify days of the week
94
+ As a Ruby dev, I want to generate all the datetime blocks of **9:00AM - 10:30AM** and **2:00PM - 2:30PM**, on **Mondays**, **Wednesdays**, and **Thursdays**, between the dates of **May 23, 2024** and **June 12, 2024**, inclusive. I can do this using the `days_of_week` parameter. This can be represented visually as:
70
95
 
71
96
  <div align="center">
72
97
  <img width="558" alt="calendar_image_1" src="https://github.com/StevenJL/periodoxical/assets/2191808/e92fc6ff-03fd-44ed-a955-d3a0dd0f5d0a">
@@ -89,8 +114,8 @@ Periodoxical.generate(
89
114
  end_time: '2:30PM'
90
115
  }
91
116
  ],
92
- start_date: '2024-05-23',
93
- end_date: '2024-06-12',
117
+ starting_from: '2024-05-23',
118
+ ending_at: '2024-06-12',
94
119
  )
95
120
  # returns an array of hashes, each with :start and :end keys
96
121
  #=>
@@ -115,9 +140,9 @@ Periodoxical.generate(
115
140
  ]
116
141
  ```
117
142
 
118
- ### Example 3 - using the `limit` key.
143
+ ### Example using the `limit` parameter.
119
144
 
120
- As a ruby dev, I want to generate the next **3** datetime blocks of **9:00AM - 10:30AM** and **2:00PM - 2:30PM** on **Sundays**, after **May 23, 2024** using the `limit` key.
145
+ As a ruby dev, I want to generate the next **3** datetime blocks of **9:00AM - 10:30AM** and **2:00PM - 2:30PM** on **Sundays**, after **May 23, 2024**. I can do this using the `limit` parameter, instead of `ending_at`.
121
146
 
122
147
  ```rb
123
148
  Periodoxical.generate(
@@ -133,7 +158,7 @@ Periodoxical.generate(
133
158
  end_time: '2:30PM'
134
159
  }
135
160
  ],
136
- start_date: Date.parse('2024-05-23'), # Can also pass in `Date` object.
161
+ starting_from: Date.parse('2024-05-23'), # Can also pass in `Date` object.
137
162
  limit: 3
138
163
  )
139
164
  # =>
@@ -153,9 +178,9 @@ Periodoxical.generate(
153
178
  ]
154
179
  ```
155
180
 
156
- ### Example 4 - when time blocks vary between days
181
+ ### Time blocks that vary between days-of-the-week
157
182
 
158
- As a ruby dev, I want to generate all the timeblocks between **May 23, 2024** and **June 12, 2024** where the time should be **8AM-9AM** on **Mondays**, but **10:45AM-12:00PM** and **2:00PM-4:00PM** on **Wednesdays**, and **2:30PM-4:15PM** on **Thursdays**.
183
+ As a ruby dev, I want to generate all the timeblocks between **May 23, 2024** and **June 12, 2024** where the time should be **8AM-9AM** on **Mondays**, but **10:45AM-12:00PM** and **2:00PM-4:00PM** on **Wednesdays**, and **2:30PM-4:15PM** on **Thursdays**. I can do this using the `day_of_week_time_blocks` parameter.
159
184
 
160
185
  <div align="center">
161
186
  <img width="628" alt="calendar_image_2" src="https://github.com/StevenJL/periodoxical/assets/2191808/26d14824-08ff-481a-97e2-9b6b11beea29">
@@ -167,8 +192,8 @@ As a ruby dev, I want to generate all the timeblocks between **May 23, 2024** an
167
192
  ```rb
168
193
  Periodoxical.generate(
169
194
  time_zone: 'America/Los_Angeles',
170
- start_date: Date.parse('2024-05-23'), # can also pass in Date objects
171
- end_date: Date.parse('2024-06-12'), # can also pass in Date objects,
195
+ starting_from: Date.parse('2024-05-23'), # can also pass in Date objects
196
+ ending_at: Date.parse('2024-06-12'), # can also pass in Date objects,
172
197
  day_of_week_time_blocks: {
173
198
  mon: [
174
199
  { start_time: '8:00AM', end_time: '9:00AM' },
@@ -184,14 +209,14 @@ Periodoxical.generate(
184
209
  )
185
210
  ```
186
211
 
187
- ### Example 5 - when specifying time blocks using day-of-month and/or week-of-month and/or month.
212
+ ### Specifying time blocks using rules for day-of-month and/or week-of-month and/or month.
188
213
 
189
- As a Ruby dev, I want to generate the next 3 timeblocks for **8AM - 9AM** for the **5th** and **10th** day of every month starting from **June**
214
+ As a Ruby dev, I want to generate the next 3 timeblocks for **8AM - 9AM** for the **5th** and **10th** day of every month starting from **June**. I can do this using the `days_of_month` parameter.
190
215
 
191
216
  ```rb
192
217
  Periodoxical.generate(
193
218
  time_zone: 'America/Los_Angeles',
194
- start_date: '2024-06-1',
219
+ starting_from: '2024-06-01',
195
220
  limit: 3,
196
221
  days_of_month: [5, 10],
197
222
  time_blocks: [
@@ -215,12 +240,12 @@ Periodoxical.generate(
215
240
  ]
216
241
  ```
217
242
 
218
- As a Ruby dev, I want to generate **4** timeblocks for **8AM - 9AM** on **Mondays** but only in the **first two weeks** in the months of **April, May, and June**
243
+ As a Ruby dev, I want to generate **4** timeblocks for **8AM - 9AM** on **Mondays** but only in the **first two weeks** in the months of **April, May, and June**. I can do this using the `months` parameter.
219
244
 
220
245
  ```
221
246
  Periodoxical.generate(
222
247
  time_zone: 'America/Los_Angeles',
223
- start_date: '2024-04-1',
248
+ starting_from: '2024-04-01',
224
249
  limit: 4,
225
250
  weeks_of_month: [1 2],
226
251
  months: [4, 5, 6],
@@ -256,11 +281,11 @@ As a Ruby dev, I want to generate timeblocks for **8AM - 9AM** on the **first an
256
281
  ```rb
257
282
  Periodoxical.generate(
258
283
  time_zone: 'America/Los_Angeles',
259
- start_date: '2024-06-01',
284
+ starting_from: '2024-06-01',
260
285
  limit: 5,
261
286
  nth_day_of_week_in_month: {
262
287
  mon: [1, 2], # valid values: -1,1,2,3,4,5
263
- fri: [-1], # Use -1 to specify "last" of the month.
288
+ fri: [-1], # Use -1 to specify the last Friday of the month.
264
289
  },
265
290
  time_blocks: [
266
291
  { start_time: '8:00AM', end_time: '9:00AM' },
@@ -292,12 +317,12 @@ Periodoxical.generate(
292
317
  ```
293
318
 
294
319
  ### Example 7 - Exclude time blocks using the `exclusion_dates` and `exclusion_times` parameters
295
- As a Ruby dev, I want to generate timeblocks for **8AM - 9AM** on **Mondays**, except for the **Monday of June 10, 2024**.
320
+ As a Ruby dev, I want to generate timeblocks for **8AM - 9AM** on **Mondays**, except for the **Monday of June 10, 2024**. I can do this using the `exlcusion_dates` parameter.
296
321
 
297
322
  ```rb
298
323
  Periodoxical.generate(
299
324
  time_zone: 'America/Los_Angeles',
300
- start_date: '2024-06-3',
325
+ starting_from: '2024-06-03',
301
326
  limit: 4,
302
327
  exclusion_dates: %w(2024-06-10),
303
328
  day_of_week_time_blocks: {
@@ -333,7 +358,7 @@ As a Ruby dev, I want to generate timeblocks for **8AM - 9AM**, and **10AM - 11A
333
358
  ```rb
334
359
  Periodoxical.generate(
335
360
  time_zone: 'America/Los_Angeles',
336
- start_date: '2024-06-3',
361
+ starting_from: '2024-06-03',
337
362
  limit: 4,
338
363
  days_of_week: %(mon),
339
364
  time_blocks: [
@@ -379,7 +404,7 @@ Periodoxical.generate(
379
404
 
380
405
  ### Example 8 - Every-other-nth day-of-week rules (ie. every other Tuesday, every 3rd Wednesday, every 10th Friday)
381
406
 
382
- As a Ruby dev, I want to generate timeblocks for **9AM- 10AM** on **every Monday**, but **every other Tuesday**, and **every other 3rd Wednesday**. I can do this using the `days_of_week` parameter, but also using the `every` and `every_other_nth` keys to specify the every-other-nth-rules.
407
+ As a Ruby dev, I want to generate timeblocks for **9AM- 10AM** on **every Monday**, but **every other Tuesday**, and **every other 3rd Wednesday**. I can do this using the `days_of_week` parameter with the `every` and `every_other_nth` keys to specify the every-other-nth-rules.
383
408
 
384
409
  This can be visualized as:
385
410
 
@@ -393,11 +418,11 @@ This can be visualized as:
393
418
  ```rb
394
419
  Periodoxical.generate(
395
420
  time_zone: 'America/Los_Angeles',
396
- start_date: '2024-12-30',
421
+ starting_from: '2024-12-30',
397
422
  days_of_week: {
398
423
  mon: { every: true }, # every Monday (no skipping)
399
- tue: { every_other_nth: 2 }, # every other Tuesday starting at first Tuesday from start date
400
- wed: { every_other_nth: 3 }, # every 3rd Wednesday starting at first Wednesday from start date
424
+ tue: { every_other_nth: 2 }, # every other Tuesday starting at first Tuesday from `starting_from` date
425
+ wed: { every_other_nth: 3 }, # every 3rd Wednesday starting at first Wednesday from `starting_from` date
401
426
  },
402
427
  limit: 10,
403
428
  time_blocks: [
@@ -456,7 +481,7 @@ Generate all the Friday the 13ths ever since May 1980 (when the first Friday the
456
481
  ```rb
457
482
  Periodoxical.generate(
458
483
  time_zone: 'America/Los_Angeles',
459
- start_date: '1980-05-01',
484
+ starting_from: '1980-05-01',
460
485
  days_of_week: %w(fri),
461
486
  days_of_month: [13],
462
487
  limit: 100,
@@ -491,7 +516,7 @@ Generate the next 10 Thanksgivings from now on (Thanksgivings is defined as the
491
516
  ```rb
492
517
  Periodoxical.generate(
493
518
  time_zone: 'America/Los_Angeles',
494
- start_date: '2024-05-01',
519
+ starting_from: '2024-05-01',
495
520
  months: [11],
496
521
  nth_day_of_week_in_month: {
497
522
  thu: [4],
@@ -0,0 +1,70 @@
1
+ module Periodoxical
2
+ module Helpers
3
+ def deep_symbolize_keys(obj)
4
+ return unless obj
5
+
6
+ case obj
7
+ when Hash
8
+ obj.each_with_object({}) do |(key, value), result|
9
+ symbolized_key = key.to_sym rescue key
10
+ result[symbolized_key] = deep_symbolize_keys(value)
11
+ end
12
+ when Array
13
+ obj.map { |e| deep_symbolize_keys(e) }
14
+ else
15
+ obj
16
+ end
17
+ end
18
+
19
+ # @param [Hash] time_block_1, time_block_2
20
+ # Ex: {
21
+ # start: #<DateTime>,
22
+ # end: #<DateTime>,
23
+ # }
24
+ def overlap?(time_block_1, time_block_2)
25
+ tb_1_start = time_block_1[:start]
26
+ tb_1_end = time_block_1[:end]
27
+ tb_2_start = time_block_2[:start]
28
+ tb_2_end = time_block_2[:end]
29
+
30
+ # Basicall overlap is when one starts before the other has ended
31
+ return true if tb_1_end > tb_2_start && tb_1_end < tb_2_end
32
+ # By symmetry
33
+ return true if tb_2_end > tb_1_start && tb_2_end < tb_1_end
34
+
35
+ false
36
+ end
37
+
38
+ def date_object_from(dt)
39
+ return unless dt
40
+ return dt if dt.is_a?(Date) || dt.is_a?(DateTime)
41
+
42
+ if dt.is_a?(String)
43
+ return Date.parse(dt) if /\A\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]\d|3[01])\z/ =~ dt
44
+
45
+ if /\A\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])T([01]\d|2[0-3]):[0-5]\d:[0-5]\d(\.\d+)?(Z|[+-][01]\d:[0-5]\d)?\z/ =~ dt
46
+ # convert to DateTime object
47
+ dt = DateTime.parse(dt)
48
+ # convert to given time_zone
49
+ return dt.to_time.localtime(@time_zone.utc_offset).to_datetime
50
+ end
51
+
52
+ raise "Could not parse date/datetime string #{dt}. Please README for examples."
53
+ else
54
+ raise "Invalid argument: #{dt}"
55
+ end
56
+ end
57
+
58
+ def day_of_week_long_to_short(dow)
59
+ {
60
+ "Monday" => "mon",
61
+ "Tuesday" => "tue",
62
+ "Wednesday" => "wed",
63
+ "Thursday" => "thu",
64
+ "Friday" => "fri",
65
+ "Saturday" => "sat",
66
+ "Sunday" => "sun",
67
+ }[dow]
68
+ end
69
+ end
70
+ end
@@ -96,8 +96,8 @@ module Periodoxical
96
96
  end
97
97
  end
98
98
 
99
- unless( @limit || @end_date)
100
- raise "Either `limit` or `end_date` must be provided"
99
+ unless( @limit || @ending_at)
100
+ raise "Either `limit` or `ending_at` must be provided"
101
101
  end
102
102
 
103
103
  if @exclusion_times
@@ -1,3 +1,3 @@
1
1
  module Periodoxical
2
- VERSION = "0.9.3"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/periodoxical.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "periodoxical/version"
2
2
  require "periodoxical/validation"
3
+ require "periodoxical/helpers"
3
4
  require "date"
4
5
  require "time"
5
6
  require "tzinfo"
@@ -14,11 +15,12 @@ module Periodoxical
14
15
 
15
16
  class Core
16
17
  include Periodoxical::Validation
18
+ include Periodoxical::Helpers
17
19
  # @param [String] time_zone
18
20
  # Ex: 'America/Los_Angeles', 'America/Chicago',
19
21
  # TZInfo::DataTimezone#name from the tzinfo gem (https://github.com/tzinfo/tzinfo)
20
- # @param [Date, String] start_date
21
- # @param [Date, String] end_date
22
+ # @param [Date, String] starting_from
23
+ # @param [Date, String] ending_at
22
24
  # @param [Array<Hash>] time_blocks
23
25
  # Ex: [
24
26
  # {
@@ -40,7 +42,7 @@ module Periodoxical
40
42
  # @param [Array<Integer>, nil] months
41
43
  # Months as integers, where 1 = Jan, 12 = Dec
42
44
  # @param [Integer] limit
43
- # How many date times to generate. To be used when `end_date` is nil.
45
+ # How many date times to generate. To be used when `ending_at` is nil.
44
46
  # @param [Aray<String>] exclusion_dates
45
47
  # Dates to be excluded when generating the time blocks
46
48
  # Ex: ['2024-06-10', '2024-06-14']
@@ -65,8 +67,8 @@ module Periodoxical
65
67
  # fri: { start_time: '7:00PM', end_time: '9:00PM' },
66
68
  # }
67
69
  def initialize(
68
- start_date:,
69
- end_date: nil,
70
+ starting_from:,
71
+ ending_at: nil,
70
72
  time_blocks: nil,
71
73
  day_of_week_time_blocks: nil,
72
74
  limit: nil,
@@ -82,24 +84,24 @@ module Periodoxical
82
84
 
83
85
  @time_zone = TZInfo::Timezone.get(time_zone)
84
86
  if days_of_week.is_a?(Array)
85
- @days_of_week = days_of_week
87
+ @days_of_week = deep_symbolize_keys(days_of_week)
86
88
  elsif days_of_week.is_a?(Hash)
87
- @days_of_week_with_alternations = days_of_week
89
+ @days_of_week_with_alternations = deep_symbolize_keys(days_of_week)
88
90
  end
89
- @nth_day_of_week_in_month = nth_day_of_week_in_month
91
+ @nth_day_of_week_in_month = deep_symbolize_keys(nth_day_of_week_in_month)
90
92
  @days_of_month = days_of_month
91
93
  @weeks_of_month = weeks_of_month
92
94
  @months = months
93
- @time_blocks = time_blocks
94
- @day_of_week_time_blocks = day_of_week_time_blocks
95
- @start_date = start_date.is_a?(String) ? Date.parse(start_date) : start_date
96
- @end_date = end_date.is_a?(String) ? Date.parse(end_date) : end_date
95
+ @time_blocks = deep_symbolize_keys(time_blocks)
96
+ @day_of_week_time_blocks = deep_symbolize_keys(day_of_week_time_blocks)
97
+ @starting_from = date_object_from(starting_from)
98
+ @ending_at = date_object_from(ending_at)
97
99
  @limit = limit
98
100
  @exclusion_dates = if exclusion_dates && !exclusion_dates.empty?
99
101
  exclusion_dates.map { |ed| Date.parse(ed) }
100
102
  end
101
103
  @exclusion_times = if exclusion_times
102
- exclusion_times.map do |et|
104
+ deep_symbolize_keys(exclusion_times).map do |et|
103
105
  { start: DateTime.parse(et[:start]), end: DateTime.parse(et[:end]) }
104
106
  end
105
107
  end
@@ -130,18 +132,6 @@ module Periodoxical
130
132
 
131
133
  private
132
134
 
133
- def day_of_week_long_to_short(dow)
134
- {
135
- "Monday" => "mon",
136
- "Tuesday" => "tue",
137
- "Wednesday" => "wed",
138
- "Thursday" => "thu",
139
- "Friday" => "fri",
140
- "Saturday" => "sat",
141
- "Sunday" => "sun",
142
- }[dow]
143
- end
144
-
145
135
  # @param [String] time_str
146
136
  # Ex: '9:00AM'
147
137
  # @param [Date] date
@@ -174,7 +164,11 @@ module Periodoxical
174
164
  # Variables which manage flow of looping through time and generating slots
175
165
  def initialize_looping_variables!
176
166
  @output = []
177
- @current_date = @start_date
167
+ if @starting_from.is_a?(DateTime)
168
+ @current_date = @starting_from.to_date
169
+ else
170
+ @current_date = @starting_from
171
+ end
178
172
  @current_day_of_week = day_of_week_long_to_short(@current_date.strftime("%A"))
179
173
  @current_count = 0
180
174
  @keep_generating = true
@@ -205,6 +199,7 @@ module Periodoxical
205
199
  def append_to_output_and_check_limit(time_block)
206
200
  # Check if this particular time is conflicts with any times from `exclusion_times`.
207
201
  return if overlaps_with_an_excluded_time?(time_block)
202
+ return if before_starting_from_or_after_ending_at?(time_block)
208
203
 
209
204
  @output << {
210
205
  start: time_str_to_object(@current_date, time_block[:start_time]),
@@ -224,7 +219,7 @@ module Periodoxical
224
219
 
225
220
  @current_day_of_week = day_of_week_long_to_short(@current_date.strftime("%A"))
226
221
 
227
- if @end_date && (@current_date > @end_date)
222
+ if @ending_at && (@current_date > @ending_at)
228
223
  @keep_generating = false
229
224
  end
230
225
 
@@ -232,7 +227,7 @@ module Periodoxical
232
227
  # there is bug, or poorly specified rules. If @current_date goes into
233
228
  # 1000 years in the future, but still no dates have been generated yet, this is
234
229
  # most likely an infinite loop situation, and needs to be killed.
235
- if @limit && ((@current_date - @start_date).to_i > 365000) && @output.empty?
230
+ if @limit && ((@current_date - @starting_from).to_i > 365000) && @output.empty?
236
231
  raise "No end condition detected, causing infinite loop. Please check rules/conditions or raise github issue for potential bug fixed"
237
232
  end
238
233
  end
@@ -324,8 +319,8 @@ module Periodoxical
324
319
  # end_time: '10:30AM'
325
320
  # },
326
321
  # ],
327
- # start_date: '2024-05-23',
328
- # end_date: '2024-05-27',
322
+ # starting_from: '2024-05-23',
323
+ # ending_at: '2024-05-27',
329
324
  # )
330
325
  # where if we don't specify any date-of-week/month constraints, we return all consecutive dates.
331
326
  # In the future, if we don't support this case, we can use `false` as the return value.
@@ -373,6 +368,29 @@ module Periodoxical
373
368
  @days_of_week_running_tally[@current_day_of_week.to_sym] = @days_of_week_running_tally[@current_day_of_week.to_sym] + 1
374
369
  end
375
370
 
371
+ # @return [Boolean]
372
+ # Used only when `starting_from` and `ending_at` are instances of DateTime
373
+ # instead of Date, requiring more precision, calculation.
374
+ def before_starting_from_or_after_ending_at?(time_block)
375
+ return false unless @starting_from.is_a?(DateTime) || @ending_at.is_a?(DateTime)
376
+
377
+ if @starting_from.is_a?(DateTime)
378
+ start_time = time_str_to_object(@current_date, time_block[:start_time])
379
+
380
+ # If the candidate time block is starting earlier than @starting_from, we want to skip it
381
+ return true if start_time < @starting_from
382
+ end
383
+
384
+ if @ending_at.is_a?(DateTime)
385
+ end_time = time_str_to_object(@current_date, time_block[:end_time])
386
+
387
+ # If the candidate time block is ending after @ending_at, we want to skip it
388
+ return true if end_time > @ending_at
389
+ end
390
+
391
+ false
392
+ end
393
+
376
394
  # @return [Boolean]
377
395
  # Whether or not the given `time_block` in the @current_date and
378
396
  # @time_zone overlaps with the times in `exclusion_times`.
@@ -391,24 +409,5 @@ module Periodoxical
391
409
 
392
410
  false
393
411
  end
394
-
395
- # @param [Hash] time_block_1, time_block_2
396
- # Ex: {
397
- # start: #<DateTime>,
398
- # end: #<DateTime>,
399
- # }
400
- def overlap?(time_block_1, time_block_2)
401
- tb_1_start = time_block_1[:start]
402
- tb_1_end = time_block_1[:end]
403
- tb_2_start = time_block_2[:start]
404
- tb_2_end = time_block_2[:end]
405
-
406
- # Basicall overlap is when one starts before the other has ended
407
- return true if tb_1_end > tb_2_start && tb_1_end < tb_2_end
408
- # By symmetry
409
- return true if tb_2_end > tb_1_start && tb_2_end < tb_1_end
410
-
411
- false
412
- end
413
412
  end
414
413
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: periodoxical
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Li
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-04 00:00:00.000000000 Z
11
+ date: 2024-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -125,7 +125,6 @@ extra_rdoc_files: []
125
125
  files:
126
126
  - ".gitignore"
127
127
  - ".rspec"
128
- - ".travis.yml"
129
128
  - CODE_OF_CONDUCT.md
130
129
  - Gemfile
131
130
  - Gemfile.lock
@@ -135,6 +134,7 @@ files:
135
134
  - bin/console
136
135
  - bin/setup
137
136
  - lib/periodoxical.rb
137
+ - lib/periodoxical/helpers.rb
138
138
  - lib/periodoxical/validation.rb
139
139
  - lib/periodoxical/version.rb
140
140
  - periodoxical.gemspec
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.10
7
- before_install: gem install bundler -v 1.17.2