periodoxical 0.2.2 → 0.4.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +83 -17
- data/lib/periodoxical/version.rb +1 -1
- data/lib/periodoxical.rb +45 -14
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 95c80ef1e3008c4279f58b029a0790353aae3b346d809390c38961b719c635a9
|
|
4
|
+
data.tar.gz: 8531378c87459b8dc1945984da0c12b11238a6895668885751923779df3c1bd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 899994a59c14f4c6dcf3e8534e7812496ebf53a8b902506e2efebd695d193abf9a93844ccd42389dc2be35c22f2ca829a0d19e3d1de44f7fa4b28d0f5baf3e79
|
|
7
|
+
data.tar.gz: fdc25739ed5cf90e3aa1a71617c927382ed56dcbf7b2b292844bc3c3bbd5f4688fc9bf6c03ccddc58e8e930435835833d9fd092c30a31cdef0a243d19c1ad19d
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
_"Up, and down, and in the end, it's only round and round and round..._" - Pink Floyd, "Us and Them"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
<div align="center">
|
|
6
|
+
<img width="558" alt="pink_floyd_time" src="https://github.com/StevenJL/periodoxical/assets/2191808/8bab4a14-2df7-42d0-b6ae-f6b57a353500">
|
|
7
|
+
<p><i>(Image Courtesy of "Pink Floyd: Time," directed by Ian Eames , ©1973)</i></p>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<br>
|
|
11
|
+
|
|
12
|
+
Generate periodic datetime blocks based on provided rules/conditions. Great for (but not limited to) calendar and scheduling applications. See Usage for detailed examples.
|
|
7
13
|
|
|
8
14
|
## Installation
|
|
9
15
|
|
|
@@ -23,7 +29,15 @@ Or install it yourself as:
|
|
|
23
29
|
|
|
24
30
|
## Usage
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
#### Example 1
|
|
33
|
+
As a Ruby dev, I want to generate all the datetimes 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:
|
|
34
|
+
|
|
35
|
+
<div align="center">
|
|
36
|
+
<img width="558" alt="calendar_image_1" src="https://github.com/StevenJL/periodoxical/assets/2191808/e92fc6ff-03fd-44ed-a955-d3a0dd0f5d0a">
|
|
37
|
+
<p><i>(image courtesy of Cal.com)</i></p>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<br>
|
|
27
41
|
|
|
28
42
|
```rb
|
|
29
43
|
Periodoxical.generate(
|
|
@@ -39,46 +53,98 @@ Periodoxical.generate(
|
|
|
39
53
|
end_time: '2:30PM'
|
|
40
54
|
}
|
|
41
55
|
],
|
|
42
|
-
start_date:
|
|
43
|
-
end_date:
|
|
56
|
+
start_date: '2024-05-23',
|
|
57
|
+
end_date: '2024-06-12',
|
|
44
58
|
)
|
|
45
|
-
# returns an array of hashes, each with
|
|
59
|
+
# returns an array of hashes, each with :start and :end keys
|
|
46
60
|
#=>
|
|
47
61
|
[
|
|
48
62
|
{
|
|
49
|
-
start: #<DateTime: 2024-05-
|
|
50
|
-
end: #<DateTime: 2024-05-
|
|
63
|
+
start: #<DateTime: 2024-05-23T09:00:00-0700">,
|
|
64
|
+
end: #<DateTime: 2024-05-23T22:30:00-0700">,
|
|
51
65
|
},
|
|
52
66
|
{
|
|
53
|
-
start: #<DateTime: 2024-05-
|
|
54
|
-
end: #<DateTime: 2024-05-
|
|
67
|
+
start: #<DateTime: 2024-05-23T14:00:00-0700>,
|
|
68
|
+
end: #<DateTime: 2024-05-23T14:30:00-0700>,
|
|
55
69
|
},
|
|
56
70
|
{
|
|
57
|
-
start: #<DateTime: 2024-05-
|
|
58
|
-
end: #<DateTime: 2024-05-
|
|
71
|
+
start: #<DateTime: 2024-05-27T09:00:00-0700>,
|
|
72
|
+
end: #<DateTime: 2024-05-27T22:30:00-0700>
|
|
59
73
|
},
|
|
60
74
|
...
|
|
75
|
+
{
|
|
76
|
+
start: #<DateTime: 2024-06-12T14:00:00-0700>,
|
|
77
|
+
end: #<DateTime: 2024-06-12T14:30:00-0700>
|
|
78
|
+
}
|
|
61
79
|
]
|
|
62
80
|
```
|
|
63
81
|
|
|
64
|
-
|
|
82
|
+
#### Example 2 - using the `limit` key.
|
|
83
|
+
|
|
84
|
+
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.
|
|
65
85
|
|
|
66
86
|
```rb
|
|
67
87
|
Periodoxical.generate(
|
|
68
88
|
time_zone: 'America/Los_Angeles',
|
|
69
|
-
days_of_week: %w[
|
|
89
|
+
days_of_week: %w[sun],
|
|
70
90
|
time_blocks: [
|
|
71
91
|
{
|
|
72
92
|
start_time: '9:00AM',
|
|
73
|
-
end_time: '10:
|
|
93
|
+
end_time: '10:30PM'
|
|
74
94
|
},
|
|
75
95
|
{
|
|
76
96
|
start_time: '2:00PM',
|
|
77
97
|
end_time: '2:30PM'
|
|
78
98
|
}
|
|
79
99
|
],
|
|
80
|
-
start_date: Date.parse('2024-05-23'),
|
|
81
|
-
limit:
|
|
100
|
+
start_date: Date.parse('2024-05-23'), # Can also pass in `Date` object.
|
|
101
|
+
limit: 3
|
|
102
|
+
)
|
|
103
|
+
# =>
|
|
104
|
+
[
|
|
105
|
+
{
|
|
106
|
+
start: #<DateTime: 2024-05-26T09:00:00-0700>,
|
|
107
|
+
end: #<DateTime: 2024-05-26T22:30:00-0700>,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
start: #<DateTime: 2024-05-26T14:00:00-0700>,
|
|
111
|
+
end: #<DateTime: 2024-05-26T14:30:00-0700>,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
start: #<DateTime: 2024-06-02T09:00:00-0700>,
|
|
115
|
+
end: #<DateTime: 2024-06-02T22:30:00-0700>,
|
|
116
|
+
},
|
|
117
|
+
]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### Example 3 - when time blocks vary between days
|
|
121
|
+
|
|
122
|
+
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**.
|
|
123
|
+
|
|
124
|
+
<div align="center">
|
|
125
|
+
<img width="628" alt="calendar_image_2" src="https://github.com/StevenJL/periodoxical/assets/2191808/26d14824-08ff-481a-97e2-9b6b11beea29">
|
|
126
|
+
<p><i>(image courtesy of Cal.com)</i></p>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
<br>
|
|
130
|
+
|
|
131
|
+
```rb
|
|
132
|
+
Periodoxical.generate(
|
|
133
|
+
time_zone: 'America/Los_Angeles',
|
|
134
|
+
start_date: Date.parse('2024-05-23'), # can also pass in Date objects
|
|
135
|
+
end_date: Date.parse('2024-06-12'), # can also pass in Date objects,
|
|
136
|
+
day_of_week_time_blocks: {
|
|
137
|
+
mon: [
|
|
138
|
+
{ start_time: '8:00AM', end_time: '9:00AM' },
|
|
139
|
+
],
|
|
140
|
+
wed: [
|
|
141
|
+
{ start_time: '10:45AM', end_time: '12:00PM' },
|
|
142
|
+
{ start_time: '2:00PM', end_time: '4:00PM' },
|
|
143
|
+
],
|
|
144
|
+
thu: [
|
|
145
|
+
{ start_time: '2:30PM', end_time: '4:15PM' }
|
|
146
|
+
],
|
|
147
|
+
}
|
|
82
148
|
)
|
|
83
149
|
```
|
|
84
150
|
|
data/lib/periodoxical/version.rb
CHANGED
data/lib/periodoxical.rb
CHANGED
|
@@ -15,8 +15,8 @@ module Periodoxical
|
|
|
15
15
|
# @param [String] time_zone
|
|
16
16
|
# Ex: 'America/Los_Angeles', 'America/Chicago',
|
|
17
17
|
# TZInfo::DataTimezone#name from the tzinfo gem (https://github.com/tzinfo/tzinfo)
|
|
18
|
-
# @param [Date] start_date
|
|
19
|
-
# @param [Date] end_date
|
|
18
|
+
# @param [Date, String] start_date
|
|
19
|
+
# @param [Date, String] end_date
|
|
20
20
|
# @param [Array<Hash>] time_blocks
|
|
21
21
|
# Ex: [
|
|
22
22
|
# {
|
|
@@ -34,7 +34,7 @@ module Periodoxical
|
|
|
34
34
|
# Ex: %w(mon tue wed sat)
|
|
35
35
|
# @param [Integer] limit
|
|
36
36
|
# How many date times to generate. To be used when `end_date` is nil.
|
|
37
|
-
# @param [Hash<Hash>]
|
|
37
|
+
# @param [Hash<Hash>] day_of_week_time_blocks
|
|
38
38
|
# To be used when hours are different between days of the week
|
|
39
39
|
# Ex: {
|
|
40
40
|
# mon: [{ start_time: '10:15AM', end_time: '11:35AM' }, { start_time: '9:00AM' }, {end_time: '4:30PM'} ],
|
|
@@ -42,13 +42,13 @@ module Periodoxical
|
|
|
42
42
|
# fri: { start_time: '7:00PM', end_time: '9:00PM' },
|
|
43
43
|
# }
|
|
44
44
|
def initialize(time_zone: 'Etc/UTC', days_of_week: nil,
|
|
45
|
-
start_date:, end_date: nil, time_blocks: nil,
|
|
45
|
+
start_date:, end_date: nil, time_blocks: nil, day_of_week_time_blocks: nil, limit: nil)
|
|
46
46
|
@time_zone = TZInfo::Timezone.get(time_zone)
|
|
47
47
|
@days_of_week = days_of_week
|
|
48
48
|
@time_blocks = time_blocks
|
|
49
|
-
@
|
|
50
|
-
@start_date = start_date
|
|
51
|
-
@end_date = end_date
|
|
49
|
+
@day_of_week_time_blocks = day_of_week_time_blocks
|
|
50
|
+
@start_date = start_date.is_a?(String) ? Date.parse(start_date) : start_date
|
|
51
|
+
@end_date = end_date.is_a?(String) ? Date.parse(end_date) : end_date
|
|
52
52
|
@limit = limit
|
|
53
53
|
validate!
|
|
54
54
|
end
|
|
@@ -62,13 +62,44 @@ module Periodoxical
|
|
|
62
62
|
# ]
|
|
63
63
|
def generate
|
|
64
64
|
if @days_of_week && @time_blocks
|
|
65
|
-
|
|
65
|
+
generate_when_same_time_blocks_for_all_days
|
|
66
|
+
elsif @day_of_week_time_blocks
|
|
67
|
+
generate_when_different_time_blocks_between_days
|
|
66
68
|
end
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
private
|
|
70
72
|
|
|
71
|
-
def
|
|
73
|
+
def generate_when_different_time_blocks_between_days
|
|
74
|
+
times_output = []
|
|
75
|
+
current_date = @start_date
|
|
76
|
+
current_count = 0
|
|
77
|
+
keep_generating = true
|
|
78
|
+
while keep_generating
|
|
79
|
+
day_of_week = day_of_week_long_to_short(current_date.strftime("%A"))
|
|
80
|
+
if @day_of_week_time_blocks[day_of_week.to_sym]
|
|
81
|
+
time_blocks = @day_of_week_time_blocks[day_of_week.to_sym]
|
|
82
|
+
time_blocks.each do |tb|
|
|
83
|
+
times_output << {
|
|
84
|
+
start: time_str_to_object(current_date, tb[:start_time]),
|
|
85
|
+
end: time_str_to_object(current_date, tb[:end_time])
|
|
86
|
+
}
|
|
87
|
+
current_count = current_count + 1
|
|
88
|
+
if @limit && current_count == @limit
|
|
89
|
+
keep_generating = false
|
|
90
|
+
break
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
current_date = current_date + 1
|
|
95
|
+
if @end_date && (current_date > @end_date)
|
|
96
|
+
keep_generating = false
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
times_output
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def generate_when_same_time_blocks_for_all_days
|
|
72
103
|
times_output = []
|
|
73
104
|
current_date = @start_date
|
|
74
105
|
current_count = 0
|
|
@@ -107,16 +138,16 @@ module Periodoxical
|
|
|
107
138
|
end
|
|
108
139
|
end
|
|
109
140
|
|
|
110
|
-
if @
|
|
111
|
-
@
|
|
112
|
-
unless VALID_DAYS_OF_WEEK.include?(d)
|
|
141
|
+
if @day_of_week_time_blocks
|
|
142
|
+
@day_of_week_time_blocks.keys.each do |d|
|
|
143
|
+
unless VALID_DAYS_OF_WEEK.include?(d.to_s)
|
|
113
144
|
raise "#{d} is not a valid day of week format. Must be #{VALID_DAYS_OF_WEEK}"
|
|
114
145
|
end
|
|
115
146
|
end
|
|
116
147
|
end
|
|
117
148
|
|
|
118
|
-
unless (@days_of_week && @time_blocks) || (@
|
|
119
|
-
raise "Need to provide either `days_of_week` and `time_blocks` or `
|
|
149
|
+
unless (@days_of_week && @time_blocks) || (@day_of_week_time_blocks)
|
|
150
|
+
raise "Need to provide either `days_of_week` and `time_blocks` or `day_of_week_time_blocks`"
|
|
120
151
|
end
|
|
121
152
|
|
|
122
153
|
unless( @limit || @end_date)
|
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.
|
|
4
|
+
version: 0.4.2
|
|
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-
|
|
11
|
+
date: 2024-06-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: tzinfo
|