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 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