periodoxical 1.1.0 → 2.2.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: 2b67da50d1bba17e1d25babaa937440ccad41bf152d1df8d3adb50ff8c9199b3
4
- data.tar.gz: 954c91d5da06a9d4955fdb35576b11f1e209a8ab152825c3f09657e891787a5d
3
+ metadata.gz: ace9209a6c531a382b264e87513dc6e5075499fc90f1eba313404368d96e58ba
4
+ data.tar.gz: e1771a96128f204df520f39bfcb54d3a294c130da07d0c9f971b98908fe985ce
5
5
  SHA512:
6
- metadata.gz: ab9f0eb8538ea18407171b2d9dc435935821370f3f3d229f59d718e3e11f3eba6b6f926129274f33c5100b22a70d937ba6f9693d714f52abaf0f2a7be4965d28
7
- data.tar.gz: 64503a74a1879ae8d0cda934ad511530ff6c22e5f1aeb9fe331f0dda99ccf8d7b81c735e2d10a9c6ce468010ea64674c1d8bc86a24fa8f18aa5382cfd29facdd
6
+ metadata.gz: aaaf84f0c0af53ad1df2f595298a8327fc67574b7a35c08a27a921f0719ef6eea0990a7ee28423755f3baa0abe78d31e4bad7bcd42f82d1c9ebe6607b0fe0574
7
+ data.tar.gz: 8eed0bfd9236bb43084c0427a50ac6ce6b793411d30adffd1d12b303ae57d0cf8d5dc0281b1c654aa15584a436066dea7f1a39a5283bdc7ef398df9dde56ec5c
data/Gemfile.lock CHANGED
@@ -1,9 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- periodoxical (1.1.0)
4
+ periodoxical (2.2.0)
5
5
  tzinfo (~> 2.0, >= 2.0.0)
6
- week_of_month (= 1.2.6)
7
6
 
8
7
  GEM
9
8
  remote: https://rubygems.org/
@@ -41,7 +40,6 @@ GEM
41
40
  rspec-support (3.13.1)
42
41
  tzinfo (2.0.6)
43
42
  concurrent-ruby (~> 1.0)
44
- week_of_month (1.2.6)
45
43
 
46
44
  PLATFORMS
47
45
  arm64-darwin-22
data/README.md CHANGED
@@ -47,20 +47,20 @@ Periodoxical.generate(
47
47
  #=>
48
48
  [
49
49
  {
50
- start_time: #<DateTime: 2024-05-23T09:00:00-0700>,
51
- end_time: #<DateTime: 2024-05-23T10:30:00-0700>,
50
+ start: #<DateTime: 2024-05-23T09:00:00-0700>,
51
+ end: #<DateTime: 2024-05-23T10:30:00-0700>,
52
52
  },
53
53
  {
54
- start_time: #<DateTime: 2024-05-24T09:00:00-0700>,
55
- end_time: #<DateTime: 2024-05-24T10:30:00-0700>,
54
+ start: #<DateTime: 2024-05-24T09:00:00-0700>,
55
+ end: #<DateTime: 2024-05-24T10:30:00-0700>,
56
56
  },
57
57
  {
58
- start_time: #<DateTime: 2024-05-25T09:00:00-0700>,
59
- end_time: #<DateTime: 2024-05-25T10:30:00-0700>,
58
+ start: #<DateTime: 2024-05-25T09:00:00-0700>,
59
+ end: #<DateTime: 2024-05-25T10:30:00-0700>,
60
60
  },
61
61
  {
62
- start_time: #<DateTime: 2024-05-26T09:00:00-0700>,
63
- end_time: #<DateTime: 2024-05-26T10:30:00-0700>,
62
+ start: #<DateTime: 2024-05-26T09:00:00-0700>,
63
+ end: #<DateTime: 2024-05-26T10:30:00-0700>,
64
64
  }
65
65
  ]
66
66
  ```
@@ -209,7 +209,7 @@ Periodoxical.generate(
209
209
  )
210
210
  ```
211
211
 
212
- ### Specifying time blocks using rules for day-of-month and/or week-of-month and/or month.
212
+ ### Specifying time blocks using rules for month(s) and/or day-of-month.
213
213
 
214
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.
215
215
 
@@ -240,41 +240,6 @@ Periodoxical.generate(
240
240
  ]
241
241
  ```
242
242
 
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.
244
-
245
- ```
246
- Periodoxical.generate(
247
- time_zone: 'America/Los_Angeles',
248
- starting_from: '2024-04-01',
249
- limit: 4,
250
- weeks_of_month: [1 2],
251
- months: [4, 5, 6],
252
- days_of_week: %w(mon),
253
- time_blocks: [
254
- { start_time: '8:00AM', end_time: '9:00AM' },
255
- ],
256
- )
257
- #=>
258
- [
259
- {
260
- start_time: #<DateTime: 2024-04-01T08:00:00-0700>,
261
- end_time: #<DateTime: 2024-04-01T09:00:00-0700>,
262
- },
263
- {
264
- start_time: #<DateTime: 2024-04-08T08:00:00-0700>,
265
- end_time: #<DateTime: 2024-04-08T09:00:00-0700>,
266
- },
267
- {
268
- start_time: #<DateTime: 2024-05-06T08:00:00-0700>,
269
- end_time: #<DateTime: 2024-05-06T09:00:00-0700>,
270
- },
271
- {
272
- start_time: #<DateTime: 2024-06-03T08:00:00-0700>,
273
- end_time: #<DateTime: 2024-06-03T09:00:00-0700>,
274
- },
275
- ]
276
- ```
277
-
278
243
  ### Example 6 - Specify nth day-of-week in month (ie. first Monday of the Month, second Tuesday of the Month, last Friday of Month)
279
244
  As a Ruby dev, I want to generate timeblocks for **8AM - 9AM** on the **first and second Mondays** and **last Fridays** of every month starting in June 2024. I can do this with the `nth_day_of_week_in_month` param.
280
245
 
@@ -474,6 +439,50 @@ Periodoxical.generate(
474
439
  ]
475
440
  ```
476
441
 
442
+ ### Use the `duration` key, to automatically partition the provided `time_blocks` into smaller chunks to the given duration.
443
+
444
+ As a Ruby dev, I want to generate **30 minute** time blocks between **9:00AM - 1:00PM, and 2:00PM - 5:00PM**. Because it is too tedious to generate all 14 of these time blocks, I prefer to pass in the `duration` key and have `periodoxical` generate them for me.
445
+
446
+ N.B. If you provide a duration that conflicts with your time blocks, `periodoxical` will not return any time blocks. For example, if you specify **9:00AM - 10:00AM** but set your **duration** as 90 minutes, no time blocks are generated since we can't fit 90 minutes into an hour!
447
+
448
+
449
+ ```rb
450
+ Periodoxical.generate(
451
+ time_zone: 'America/Los_Angeles',
452
+ time_blocks: [
453
+ {
454
+ start_time: '9:00AM',
455
+ end_time: '1:00PM'
456
+ },
457
+ {
458
+ start_time: '2:00PM',
459
+ end_time: '5:00PM'
460
+ },
461
+ ],
462
+ duration: 30, #(minutes)
463
+ starting_from: '2024-05-23',
464
+ ending_at: '2024-05-26',
465
+ )
466
+ # => [
467
+ {
468
+ start: #<DateTime: 2024-05-23T09:00:00--0700>
469
+ end: #<DateTime: 2024-05-23T09:30:00--0700>
470
+ },
471
+ {
472
+ start: #<DateTime: 2024-05-23T09:30:00--0700>
473
+ end: #<DateTime: 2024-05-23T10:00:00--0700>
474
+ },
475
+ {
476
+ start: #<DateTime: 2024-05-23T10:00:00--0700>
477
+ end: #<DateTime: 2024-05-23T10:30:00--0700>
478
+ },
479
+ {
480
+ start: #<DateTime: 2024-05-23T10:30:00--0700>
481
+ end: #<DateTime: 2024-05-23T11:00:00--0700>
482
+ }
483
+ ]
484
+ ```
485
+
477
486
  ### Having Some Fun
478
487
 
479
488
  Generate all the Friday the 13ths ever since May 1980 (when the first Friday the 13th film was released).
@@ -1,3 +1,3 @@
1
1
  module Periodoxical
2
- VERSION = "1.1.0"
2
+ VERSION = "2.2.0"
3
3
  end
data/lib/periodoxical.rb CHANGED
@@ -4,7 +4,6 @@ require "periodoxical/helpers"
4
4
  require "date"
5
5
  require "time"
6
6
  require "tzinfo"
7
- require "week_of_month"
8
7
 
9
8
  module Periodoxical
10
9
  class << self
@@ -66,6 +65,12 @@ module Periodoxical
66
65
  # tue: { start_time: '11:30PM', end_time: '12:00AM' },
67
66
  # fri: { start_time: '7:00PM', end_time: '9:00PM' },
68
67
  # }
68
+ # @param [Integer] duration
69
+ # Splits the time_blocks into this duration (in minutes). For example, if time_block is 9:00AM - 10:00AM,
70
+ # and duration is 20 minutes. It creates 3 timeblocks of:
71
+ # - 9:00AM - 9:20AM
72
+ # - 9:20AM - 9:40AM
73
+ # - 9:40AM - 10:00AM
69
74
  def initialize(
70
75
  starting_from:,
71
76
  ending_at: nil,
@@ -78,7 +83,7 @@ module Periodoxical
78
83
  days_of_week: nil,
79
84
  nth_day_of_week_in_month: nil,
80
85
  days_of_month: nil,
81
- weeks_of_month: nil,
86
+ duration: nil,
82
87
  months: nil
83
88
  )
84
89
 
@@ -90,13 +95,20 @@ module Periodoxical
90
95
  end
91
96
  @nth_day_of_week_in_month = deep_symbolize_keys(nth_day_of_week_in_month)
92
97
  @days_of_month = days_of_month
93
- @weeks_of_month = weeks_of_month
94
98
  @months = months
95
99
  @time_blocks = deep_symbolize_keys(time_blocks)
96
100
  @day_of_week_time_blocks = deep_symbolize_keys(day_of_week_time_blocks)
97
101
  @starting_from = date_object_from(starting_from)
98
102
  @ending_at = date_object_from(ending_at)
99
103
  @limit = limit
104
+
105
+ if duration
106
+ unless duration.is_a?(Integer)
107
+ raise "duration must be an integer"
108
+ else
109
+ @duration = duration
110
+ end
111
+ end
100
112
  @exclusion_dates = if exclusion_dates && !exclusion_dates.empty?
101
113
  exclusion_dates.map { |ed| Date.parse(ed) }
102
114
  end
@@ -201,19 +213,31 @@ module Periodoxical
201
213
  return if overlaps_with_an_excluded_time?(time_block)
202
214
  return if before_starting_from_or_after_ending_at?(time_block)
203
215
 
204
- @output << {
205
- start: time_str_to_object(@current_date, time_block[:start_time]),
206
- end: time_str_to_object(@current_date, time_block[:end_time])
207
- }
216
+ strtm = time_str_to_object(@current_date, time_block[:start_time])
217
+ endtm = time_str_to_object(@current_date, time_block[:end_time])
208
218
 
209
- # increment count, if `limit` is used to stop generating
210
- @current_count = @current_count + 1
211
- if @limit && @current_count == @limit
212
- @keep_generating = false
213
- throw :done
219
+ if @duration
220
+ split_by_duration_and_append(strtm, endtm)
221
+ else
222
+ @output << {
223
+ start: strtm,
224
+ end: endtm
225
+ }
226
+ increment_and_check_limit
214
227
  end
215
228
  end
216
229
 
230
+ # increment count, if `limit` is used to stop generating
231
+ def increment_and_check_limit
232
+ return unless @limit
233
+
234
+ @current_count += 1
235
+ return if @current_count < @limit
236
+
237
+ @keep_generating = false
238
+ throw :done
239
+ end
240
+
217
241
  def advance_current_date_and_check_if_reached_end_date
218
242
  @current_date = @current_date + 1
219
243
 
@@ -240,11 +264,6 @@ module Periodoxical
240
264
  return false if @exclusion_dates.include?(@current_date)
241
265
  end
242
266
 
243
- # If weeks_of_months are specified but not satisified, return false
244
- if @weeks_of_month
245
- return false unless @weeks_of_month.include?(@current_date.week_of_month)
246
- end
247
-
248
267
  # If months are specified, but current_date does not satisfy months,
249
268
  # return false
250
269
  if @months
@@ -409,5 +428,20 @@ module Periodoxical
409
428
 
410
429
  false
411
430
  end
431
+
432
+ def split_by_duration_and_append(strtm, endtm)
433
+ delta = Rational(@duration, 24 * 60)
434
+ si = strtm
435
+ ei = strtm + delta
436
+ while ei <= endtm
437
+ @output << {
438
+ start: si,
439
+ end: ei
440
+ }
441
+ si += delta
442
+ ei += delta
443
+ increment_and_check_limit
444
+ end
445
+ end
412
446
  end
413
447
  end
data/periodoxical.gemspec CHANGED
@@ -35,7 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.require_paths = ["lib"]
36
36
 
37
37
  spec.add_dependency 'tzinfo', '~> 2.0', '>= 2.0.0'
38
- spec.add_dependency 'week_of_month', '1.2.6'
39
38
 
40
39
  spec.add_development_dependency "bundler", "~> 2.4"
41
40
  spec.add_development_dependency "rake", "~> 12.3.3"
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: 1.1.0
4
+ version: 2.2.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-12 00:00:00.000000000 Z
11
+ date: 2024-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -30,20 +30,6 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 2.0.0
33
- - !ruby/object:Gem::Dependency
34
- name: week_of_month
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - '='
38
- - !ruby/object:Gem::Version
39
- version: 1.2.6
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - '='
45
- - !ruby/object:Gem::Version
46
- version: 1.2.6
47
33
  - !ruby/object:Gem::Dependency
48
34
  name: bundler
49
35
  requirement: !ruby/object:Gem::Requirement