periodoxical 1.1.0 → 2.2.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -3
- data/README.md +53 -44
- data/lib/periodoxical/version.rb +1 -1
- data/lib/periodoxical.rb +51 -17
- data/periodoxical.gemspec +0 -1
- metadata +2 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ace9209a6c531a382b264e87513dc6e5075499fc90f1eba313404368d96e58ba
|
|
4
|
+
data.tar.gz: e1771a96128f204df520f39bfcb54d3a294c130da07d0c9f971b98908fe985ce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 (
|
|
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
|
-
|
|
51
|
-
|
|
50
|
+
start: #<DateTime: 2024-05-23T09:00:00-0700>,
|
|
51
|
+
end: #<DateTime: 2024-05-23T10:30:00-0700>,
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
start: #<DateTime: 2024-05-24T09:00:00-0700>,
|
|
55
|
+
end: #<DateTime: 2024-05-24T10:30:00-0700>,
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
start: #<DateTime: 2024-05-25T09:00:00-0700>,
|
|
59
|
+
end: #<DateTime: 2024-05-25T10:30:00-0700>,
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
|
-
|
|
63
|
-
|
|
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
|
|
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).
|
data/lib/periodoxical/version.rb
CHANGED
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
|
-
|
|
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
|
-
@
|
|
205
|
-
|
|
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
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
@
|
|
213
|
-
|
|
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:
|
|
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-
|
|
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
|