periodoxical 0.3.2 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +64 -16
- data/lib/periodoxical/version.rb +1 -1
- data/lib/periodoxical.rb +26 -7
- 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: fa1a430d11ca7fdd0cea524011b7164f926f87bad37a49c4848bdbca934bdc79
|
4
|
+
data.tar.gz: fea338a55f3b095b4ac6c1ff57f235e8490a9b6683ae48b9a573b0b1afba22f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74ec882770d5567ad292ad26c020777d9075cbb0bf77259f37fa0713ab239772dea1dd52fadb2d415ceb8820a10cbc2572ee4847ac181ae208d81d6d759b0517
|
7
|
+
data.tar.gz: e2a7c7b00eec3522ce4d2bd15a999a7f86de8826245c464f0e0844b3f7cd42d7eb942d80e7cad2ecbc48d66399f4962fd9f7be7d8a9d4a025e51d79b477112e2
|
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,15 +29,14 @@ Or install it yourself as:
|
|
23
29
|
|
24
30
|
## Usage
|
25
31
|
|
26
|
-
|
27
|
-
As a Ruby dev, I want to generate all the datetimes blocks of 9:00AM - 10:30AM and 2:00PM - 2:30PM
|
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:
|
28
34
|
|
29
35
|
<div align="center">
|
30
|
-
<img width="558" alt="
|
36
|
+
<img width="558" alt="calendar_image_1" src="https://github.com/StevenJL/periodoxical/assets/2191808/e92fc6ff-03fd-44ed-a955-d3a0dd0f5d0a">
|
31
37
|
<p><i>(image courtesy of Cal.com)</i></p>
|
32
38
|
</div>
|
33
39
|
|
34
|
-
|
35
40
|
<br>
|
36
41
|
|
37
42
|
```rb
|
@@ -48,8 +53,8 @@ Periodoxical.generate(
|
|
48
53
|
end_time: '2:30PM'
|
49
54
|
}
|
50
55
|
],
|
51
|
-
start_date:
|
52
|
-
end_date:
|
56
|
+
start_date: '2024-05-23',
|
57
|
+
end_date: '2024-06-12',
|
53
58
|
)
|
54
59
|
# returns an array of hashes, each with :start and :end keys
|
55
60
|
#=>
|
@@ -74,10 +79,9 @@ Periodoxical.generate(
|
|
74
79
|
]
|
75
80
|
```
|
76
81
|
|
77
|
-
|
82
|
+
#### Example 2 - using the `limit` key.
|
78
83
|
|
79
|
-
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
|
80
|
-
using the `limit` key.
|
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.
|
81
85
|
|
82
86
|
```rb
|
83
87
|
Periodoxical.generate(
|
@@ -93,7 +97,7 @@ Periodoxical.generate(
|
|
93
97
|
end_time: '2:30PM'
|
94
98
|
}
|
95
99
|
],
|
96
|
-
start_date: Date.parse('2024-05-23'),
|
100
|
+
start_date: Date.parse('2024-05-23'), # Can also pass in `Date` object.
|
97
101
|
limit: 3
|
98
102
|
)
|
99
103
|
# =>
|
@@ -113,15 +117,22 @@ Periodoxical.generate(
|
|
113
117
|
]
|
114
118
|
```
|
115
119
|
|
116
|
-
|
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**.
|
117
123
|
|
118
|
-
|
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>
|
119
130
|
|
120
131
|
```rb
|
121
132
|
Periodoxical.generate(
|
122
133
|
time_zone: 'America/Los_Angeles',
|
123
|
-
start_date: Date.parse('2024-05-23'),
|
124
|
-
end_date: Date.parse('2024-06-12'),
|
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,
|
125
136
|
day_of_week_time_blocks: {
|
126
137
|
mon: [
|
127
138
|
{ start_time: '8:00AM', end_time: '9:00AM' },
|
@@ -137,6 +148,43 @@ Periodoxical.generate(
|
|
137
148
|
)
|
138
149
|
```
|
139
150
|
|
151
|
+
#### Example 4 - Exclude time blocks using the `exclusion_dates` parameter
|
152
|
+
As a Ruby dev, I want to generate slots for 8AM - 9AM on Mondays, except for the Monday of June 10, 2024.
|
153
|
+
|
154
|
+
```rb
|
155
|
+
Periodoxical.generate(
|
156
|
+
time_zone: 'America/Los_Angeles',
|
157
|
+
start_date: '2024-06-3',
|
158
|
+
limit: 4,
|
159
|
+
exclusion_dates: %w(2024-06-10),
|
160
|
+
day_of_week_time_blocks: {
|
161
|
+
mon: [
|
162
|
+
{ start_time: '8:00AM', end_time: '9:00AM' },
|
163
|
+
],
|
164
|
+
}
|
165
|
+
)
|
166
|
+
# Returns all Monday 8AM - 9AM blocks except for the june on June 10, 2024
|
167
|
+
# =>
|
168
|
+
[
|
169
|
+
{
|
170
|
+
start: <#DateTime: 2024-06-03T08:00:00-0700>,
|
171
|
+
end: <#DateTime: 2024-06-03T09:00:00-0700>,
|
172
|
+
}
|
173
|
+
{
|
174
|
+
start: <#DateTime: 2024-06-17T08:00:00-0700>,
|
175
|
+
end: <#DateTime: 2024-06-17T09:00:00-0700>,
|
176
|
+
}
|
177
|
+
{
|
178
|
+
start: <#DateTime: 2024-06-24T08:00:00-0700>,
|
179
|
+
end: <#DateTime: 2024-06-24T09:00:00-0700>,
|
180
|
+
}
|
181
|
+
{
|
182
|
+
start: <#DateTime: 2024-07-01T08:00:00-0700>,
|
183
|
+
end: <#DateTime: 2024-07-01T09:00:00-0700>,
|
184
|
+
}
|
185
|
+
]
|
186
|
+
```
|
187
|
+
|
140
188
|
## Development
|
141
189
|
|
142
190
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
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,6 +34,9 @@ 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 [Aray<String>] exclusion_dates
|
38
|
+
# Dates to be excluded when generating the time blocks
|
39
|
+
# Ex: ['2024-06-10', '2024-06-14']
|
37
40
|
# @param [Hash<Hash>] day_of_week_time_blocks
|
38
41
|
# To be used when hours are different between days of the week
|
39
42
|
# Ex: {
|
@@ -42,14 +45,17 @@ module Periodoxical
|
|
42
45
|
# fri: { start_time: '7:00PM', end_time: '9:00PM' },
|
43
46
|
# }
|
44
47
|
def initialize(time_zone: 'Etc/UTC', days_of_week: nil,
|
45
|
-
start_date:, end_date: nil, time_blocks: nil, day_of_week_time_blocks: nil, limit: nil)
|
48
|
+
start_date:, end_date: nil, time_blocks: nil, day_of_week_time_blocks: nil, limit: nil, exclusion_dates: nil)
|
46
49
|
@time_zone = TZInfo::Timezone.get(time_zone)
|
47
50
|
@days_of_week = days_of_week
|
48
51
|
@time_blocks = time_blocks
|
49
52
|
@day_of_week_time_blocks = day_of_week_time_blocks
|
50
|
-
@start_date = start_date
|
51
|
-
@end_date = end_date
|
53
|
+
@start_date = start_date.is_a?(String) ? Date.parse(start_date) : start_date
|
54
|
+
@end_date = end_date.is_a?(String) ? Date.parse(end_date) : end_date
|
52
55
|
@limit = limit
|
56
|
+
@exclusion_dates = if exclusion_dates && !exclusion_dates.empty?
|
57
|
+
exclusion_dates.map { |ed| Date.parse(ed) }
|
58
|
+
end
|
53
59
|
validate!
|
54
60
|
end
|
55
61
|
|
@@ -77,7 +83,7 @@ module Periodoxical
|
|
77
83
|
keep_generating = true
|
78
84
|
while keep_generating
|
79
85
|
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]
|
86
|
+
if @day_of_week_time_blocks[day_of_week.to_sym] && !excluded_date?(current_date)
|
81
87
|
time_blocks = @day_of_week_time_blocks[day_of_week.to_sym]
|
82
88
|
time_blocks.each do |tb|
|
83
89
|
times_output << {
|
@@ -106,7 +112,7 @@ module Periodoxical
|
|
106
112
|
keep_generating = true
|
107
113
|
while keep_generating
|
108
114
|
day_of_week = day_of_week_long_to_short(current_date.strftime("%A"))
|
109
|
-
if @days_of_week.include?(day_of_week)
|
115
|
+
if @days_of_week.include?(day_of_week) && !excluded_date?(current_date)
|
110
116
|
@time_blocks.each do |tb|
|
111
117
|
times_output << {
|
112
118
|
start: time_str_to_object(current_date, tb[:start_time]),
|
@@ -182,5 +188,18 @@ module Periodoxical
|
|
182
188
|
)
|
183
189
|
@time_zone.local_to_utc(date_time).new_offset(@time_zone.current_period.offset.utc_total_offset)
|
184
190
|
end
|
191
|
+
|
192
|
+
# @param [Date] current_date
|
193
|
+
# @return [Boolean]
|
194
|
+
# Whether or not the date is excluded
|
195
|
+
def excluded_date?(current_date)
|
196
|
+
return false unless @exclusion_dates
|
197
|
+
|
198
|
+
@exclusion_dates.each do |ed|
|
199
|
+
return true if current_date == ed
|
200
|
+
end
|
201
|
+
|
202
|
+
false
|
203
|
+
end
|
185
204
|
end
|
186
205
|
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.
|
4
|
+
version: 0.5.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
|