periodoxical 0.1.2 → 0.3.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: 566ebd2f1dcb17516ed1c3deae4b8a51639daa61709f3e850131b6524d158004
4
- data.tar.gz: cb121164fc25bd1c975d8df101fbcf5f8b523b5e7f7ea421385fd80b9aaebf3d
3
+ metadata.gz: d5a035b48977603a07dc33634bd290fab82ccee9844056cea809ea7b1b6dcdd9
4
+ data.tar.gz: 397ac66e80143a549f8ebb51c0ada7cb1e275491d5c91d6444707f06f52a2d3d
5
5
  SHA512:
6
- metadata.gz: f3b56cbc4e282596b4aa87572ba659711b7342f5413a8f5db293d44888abb0075a7c637cae99fabb7887428960900faba0fed66160fefd56d5c4f43f14c64892
7
- data.tar.gz: 2015f24e0209d01e3fde60ee750ea2c9c7865bc07447a7c73514ea935ddc2e9024769f3e7201745e3ef09b3d47a569169de6898cb435f4ecd46f745eb94f0d36
6
+ metadata.gz: ed99e7495d51df3865bc8e555f4b8ccdd259b94a661dd6fe3f257d4fa1196d86c6775faf0fbe1adfb013dba31c2e1cbfd7f2d563ffce56febebc2b01d7077c7e
7
+ data.tar.gz: 1fb4a1626239919706784d2ba638c51d2e0316f69ac8baa4833d9a6a029d15fc6ad6b0f3c52c362655b88bc08f719199b98d03e6d03306f189947df0d941b907
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- periodoxical (0.1.1)
4
+ periodoxical (0.3.2)
5
5
  tzinfo (~> 2.0, >= 2.0.0)
6
6
 
7
7
  GEM
@@ -24,7 +24,7 @@ GEM
24
24
  pry-stack_explorer (0.6.1)
25
25
  binding_of_caller (~> 1.0)
26
26
  pry (~> 0.13)
27
- rake (10.5.0)
27
+ rake (12.3.3)
28
28
  rspec (3.13.0)
29
29
  rspec-core (~> 3.13.0)
30
30
  rspec-expectations (~> 3.13.0)
@@ -49,7 +49,7 @@ DEPENDENCIES
49
49
  periodoxical!
50
50
  pry-byebug (~> 3.10)
51
51
  pry-stack_explorer (~> 0.6)
52
- rake (~> 10.0)
52
+ rake (~> 12.3.3)
53
53
  rspec (~> 3.0)
54
54
 
55
55
  BUNDLED WITH
data/README.md CHANGED
@@ -23,11 +23,18 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
- ```rb
27
- # Generates 9:00AM - 10:30AM and 2:00PM - 2:30PM time blocks
28
- # on Mondays, Wednesdays, and Thursdays, between the dates of
29
- # May 23, 2024 and June 24, 2024
26
+ ##### Example 1
27
+ 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
+
29
+ <div align="center">
30
+ <img width="558" alt="Screenshot 2024-05-28 at 10 55 45 PM" src="https://github.com/StevenJL/periodoxical/assets/2191808/e92fc6ff-03fd-44ed-a955-d3a0dd0f5d0a">
31
+ <p><i>(image courtesy of Cal.com)</i></p>
32
+ </div>
33
+
30
34
 
35
+ <br>
36
+
37
+ ```rb
31
38
  Periodoxical.generate(
32
39
  time_zone: 'America/Los_Angeles',
33
40
  days_of_week: %w[mon wed thu],
@@ -42,27 +49,94 @@ Periodoxical.generate(
42
49
  }
43
50
  ],
44
51
  start_date: Date.parse('2024-05-23'),
45
- end_date: Date.parse('2024-06-24')
52
+ end_date: Date.parse('2024-06-12')
46
53
  )
47
- # returns an array of hashes, each with a :start, :end
54
+ # returns an array of hashes, each with :start and :end keys
48
55
  #=>
49
56
  [
50
57
  {
51
- start: #<DateTime: 2024-05-23T16:00:00+00:00>,
52
- end: #<DateTime: 2024-05-24T05:30:00+00:00>,
58
+ start: #<DateTime: 2024-05-23T09:00:00-0700">,
59
+ end: #<DateTime: 2024-05-23T22:30:00-0700">,
53
60
  },
54
61
  {
55
- start: #<DateTime: 2024-05-23T21:00:00+00:00>,
56
- end: #<DateTime: 2024-05-23T21:30:00+00:00>,
62
+ start: #<DateTime: 2024-05-23T14:00:00-0700>,
63
+ end: #<DateTime: 2024-05-23T14:30:00-0700>,
57
64
  },
58
65
  {
59
- start: #<DateTime: 2024-05-27T16:00:00+00:00>,
60
- end: #<DateTime: 2024-05-28T05:30:00+00:00>
66
+ start: #<DateTime: 2024-05-27T09:00:00-0700>,
67
+ end: #<DateTime: 2024-05-27T22:30:00-0700>
61
68
  },
62
69
  ...
70
+ {
71
+ start: #<DateTime: 2024-06-12T14:00:00-0700>,
72
+ end: #<DateTime: 2024-06-12T14:30:00-0700>
73
+ }
63
74
  ]
64
75
  ```
65
76
 
77
+ ##### Example 2 - using the `limit` key.
78
+
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, after May 23, 2024
80
+ using the `limit` key.
81
+
82
+ ```rb
83
+ Periodoxical.generate(
84
+ time_zone: 'America/Los_Angeles',
85
+ days_of_week: %w[sun],
86
+ time_blocks: [
87
+ {
88
+ start_time: '9:00AM',
89
+ end_time: '10:30PM'
90
+ },
91
+ {
92
+ start_time: '2:00PM',
93
+ end_time: '2:30PM'
94
+ }
95
+ ],
96
+ start_date: Date.parse('2024-05-23'),
97
+ limit: 3
98
+ )
99
+ # =>
100
+ [
101
+ {
102
+ start: #<DateTime: 2024-05-26T09:00:00-0700>,
103
+ end: #<DateTime: 2024-05-26T22:30:00-0700>,
104
+ },
105
+ {
106
+ start: #<DateTime: 2024-05-26T14:00:00-0700>,
107
+ end: #<DateTime: 2024-05-26T14:30:00-0700>,
108
+ },
109
+ {
110
+ start: #<DateTime: 2024-06-02T09:00:00-0700>,
111
+ end: #<DateTime: 2024-06-02T22:30:00-0700>,
112
+ },
113
+ ]
114
+ ```
115
+
116
+ ##### Example 3 - when time blocks vary between days
117
+
118
+ 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 and 4:00PM on Wednesdays, and 2:30PM to 4:15PM on Thursdays.
119
+
120
+ ```rb
121
+ Periodoxical.generate(
122
+ time_zone: 'America/Los_Angeles',
123
+ start_date: Date.parse('2024-05-23'),
124
+ end_date: Date.parse('2024-06-12'),
125
+ day_of_week_time_blocks: {
126
+ mon: [
127
+ { start_time: '8:00AM', end_time: '9:00AM' },
128
+ ],
129
+ wed: [
130
+ { start_time: '10:45AM', end_time: '12:00PM' },
131
+ { start_time: '2:00PM', end_time: '4:00PM' },
132
+ ],
133
+ thu: [
134
+ { start_time: '2:30PM', end_time: '4:15PM' }
135
+ ],
136
+ }
137
+ )
138
+ ```
139
+
66
140
  ## Development
67
141
 
68
142
  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.
@@ -1,3 +1,3 @@
1
1
  module Periodoxical
2
- VERSION = "0.1.2"
2
+ VERSION = "0.3.2"
3
3
  end
data/lib/periodoxical.rb CHANGED
@@ -17,13 +17,24 @@ module Periodoxical
17
17
  # TZInfo::DataTimezone#name from the tzinfo gem (https://github.com/tzinfo/tzinfo)
18
18
  # @param [Date] start_date
19
19
  # @param [Date] end_date
20
+ # @param [Array<Hash>] time_blocks
21
+ # Ex: [
22
+ # {
23
+ # start_time: '9:00AM',
24
+ # end_time: '10:30PM'
25
+ # },
26
+ # {
27
+ # start_time: '2:00PM',
28
+ # end_time: '2:30PM'
29
+ # }
30
+ # ]
20
31
  # @param [Array<String>, nil] days_of_week
21
32
  # Days of the week to generate the times for, if nil, then times are generated
22
33
  # for every day.
23
34
  # Ex: %w(mon tue wed sat)
24
35
  # @param [Integer] limit
25
36
  # How many date times to generate. To be used when `end_date` is nil.
26
- # @param [Hash<Hash>] day_of_week_hours
37
+ # @param [Hash<Hash>] day_of_week_time_blocks
27
38
  # To be used when hours are different between days of the week
28
39
  # Ex: {
29
40
  # mon: [{ start_time: '10:15AM', end_time: '11:35AM' }, { start_time: '9:00AM' }, {end_time: '4:30PM'} ],
@@ -31,11 +42,11 @@ module Periodoxical
31
42
  # fri: { start_time: '7:00PM', end_time: '9:00PM' },
32
43
  # }
33
44
  def initialize(time_zone: 'Etc/UTC', days_of_week: nil,
34
- start_date:, end_date:, 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)
35
46
  @time_zone = TZInfo::Timezone.get(time_zone)
36
47
  @days_of_week = days_of_week
37
48
  @time_blocks = time_blocks
38
- @day_of_week_hours = day_of_week_hours
49
+ @day_of_week_time_blocks = day_of_week_time_blocks
39
50
  @start_date = start_date
40
51
  @end_date = end_date
41
52
  @limit = limit
@@ -51,28 +62,70 @@ module Periodoxical
51
62
  # ]
52
63
  def generate
53
64
  if @days_of_week && @time_blocks
54
- 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
55
68
  end
56
69
  end
57
70
 
58
71
  private
59
72
 
60
- def generate_from_days_of_week_time_blocks
61
- times = []
73
+ def generate_when_different_time_blocks_between_days
74
+ times_output = []
62
75
  current_date = @start_date
63
- while current_date <= @end_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
103
+ times_output = []
104
+ current_date = @start_date
105
+ current_count = 0
106
+ keep_generating = true
107
+ while keep_generating
64
108
  day_of_week = day_of_week_long_to_short(current_date.strftime("%A"))
65
109
  if @days_of_week.include?(day_of_week)
66
110
  @time_blocks.each do |tb|
67
- times << {
111
+ times_output << {
68
112
  start: time_str_to_object(current_date, tb[:start_time]),
69
113
  end: time_str_to_object(current_date, tb[:end_time])
70
114
  }
115
+ current_count = current_count + 1
116
+ if @limit && current_count == @limit
117
+ keep_generating = false
118
+ break
119
+ end
71
120
  end
72
121
  end
73
122
  current_date = current_date + 1
123
+
124
+ if @end_date && (current_date > @end_date)
125
+ keep_generating = false
126
+ end
74
127
  end
75
- times
128
+ times_output
76
129
  end
77
130
 
78
131
  def validate!
@@ -85,15 +138,20 @@ module Periodoxical
85
138
  end
86
139
  end
87
140
 
88
- if @day_of_week_hours
89
- @day_of_week_hours.keys.each do |d|
90
- 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)
91
144
  raise "#{d} is not a valid day of week format. Must be #{VALID_DAYS_OF_WEEK}"
92
145
  end
93
146
  end
94
147
  end
95
148
 
96
- unless (@days_of_week && @start_time && @end_time) || (@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`"
151
+ end
152
+
153
+ unless( @limit || @end_date)
154
+ raise "Either `limit` or `end_date` must be provided"
97
155
  end
98
156
  end
99
157
 
data/periodoxical.gemspec CHANGED
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency 'tzinfo', '~> 2.0', '>= 2.0.0'
38
38
 
39
39
  spec.add_development_dependency "bundler", "~> 2.4"
40
- spec.add_development_dependency "rake", "~> 10.0"
40
+ spec.add_development_dependency "rake", "~> 12.3.3"
41
41
  spec.add_development_dependency "rspec", "~> 3.0"
42
42
  spec.add_development_dependency "pry-byebug", "~> 3.10"
43
43
  spec.add_development_dependency "pry-stack_explorer", "~> 0.6"
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.1.2
4
+ version: 0.3.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-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '10.0'
53
+ version: 12.3.3
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '10.0'
60
+ version: 12.3.3
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rspec
63
63
  requirement: !ruby/object:Gem::Requirement