periodoxical 0.2.2 → 0.4.2

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: 86a786f06e166368721d1f0f17d9c702bfc23950f66482f4c2da80fde583d9a5
4
- data.tar.gz: 65bae069f30ee999ccc99353d03149db0e3414adbb1257b1c163e2d7cfaa5e01
3
+ metadata.gz: 95c80ef1e3008c4279f58b029a0790353aae3b346d809390c38961b719c635a9
4
+ data.tar.gz: 8531378c87459b8dc1945984da0c12b11238a6895668885751923779df3c1bd3
5
5
  SHA512:
6
- metadata.gz: e9f76a36b7a77e326ab999adbda7d59f24f84383f198c260e99b76cfb7c9fe069c10fa3ff46c61c53491e4d6b96f8c23b8378471cd7494cce21e78dbfface58e
7
- data.tar.gz: 3ad7d053bb777bf3f3dbf403a787447dc77eeab162d185a6e3de79c21a68d468ac30365aa2ad3d5db65525a2678f78e3f0c5e50e728b22cc521c205445696056
6
+ metadata.gz: 899994a59c14f4c6dcf3e8534e7812496ebf53a8b902506e2efebd695d193abf9a93844ccd42389dc2be35c22f2ca829a0d19e3d1de44f7fa4b28d0f5baf3e79
7
+ data.tar.gz: fdc25739ed5cf90e3aa1a71617c927382ed56dcbf7b2b292844bc3c3bbd5f4688fc9bf6c03ccddc58e8e930435835833d9fd092c30a31cdef0a243d19c1ad19d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- periodoxical (0.2.2)
4
+ periodoxical (0.4.2)
5
5
  tzinfo (~> 2.0, >= 2.0.0)
6
6
 
7
7
  GEM
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
- Generate periodic dates/times based on rules. Great for (but not limited to) calendar and scheduling applications.
6
- See Usage for examples/details.
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
- Generates 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 24, 2024
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: Date.parse('2024-05-23'),
43
- end_date: Date.parse('2024-06-24')
56
+ start_date: '2024-05-23',
57
+ end_date: '2024-06-12',
44
58
  )
45
- # returns an array of hashes, each with a :start, :end
59
+ # returns an array of hashes, each with :start and :end keys
46
60
  #=>
47
61
  [
48
62
  {
49
- start: #<DateTime: 2024-05-23T16:00:00+00:00>,
50
- end: #<DateTime: 2024-05-24T05:30:00+00:00>,
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-23T21:00:00+00:00>,
54
- end: #<DateTime: 2024-05-23T21:30:00+00:00>,
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-27T16:00:00+00:00>,
58
- end: #<DateTime: 2024-05-28T05:30:00+00:00>
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
- Generate the next 10 datetime blocks of 3:00PM - 4:30PM, on Sundays, after May 30, 2024
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[mon wed thu],
89
+ days_of_week: %w[sun],
70
90
  time_blocks: [
71
91
  {
72
92
  start_time: '9:00AM',
73
- end_time: '10:30AM'
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: 10
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
 
@@ -1,3 +1,3 @@
1
1
  module Periodoxical
2
- VERSION = "0.2.2"
2
+ VERSION = "0.4.2"
3
3
  end
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>] day_of_week_hours
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, day_of_week_hours: nil, limit: 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
- @day_of_week_hours = day_of_week_hours
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
- generate_from_days_of_week_time_blocks
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 generate_from_days_of_week_time_blocks
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 @day_of_week_hours
111
- @day_of_week_hours.keys.each do |d|
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) || (@day_of_week_hours)
119
- raise "Need to provide either `days_of_week` and `time_blocks` or `day_of_week_hours`"
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.2.2
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-05-24 00:00:00.000000000 Z
11
+ date: 2024-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo