Reputation: 2055
Rails 5.x
This is an appointment system, displaying all the available time (steps) every 15 minutes.
start_time = '2:00 pm'.to_time
> 2020-10-26 14:00:00 +1100
and
end_time = '5:00 pm'.to_time
> 2020-10-26 17:00:00 +1100
I got the available time every 15mins
(start_time.to_i..end_time.to_i).to_a.in_groups_of(15.minutes).collect(&:first).collect { |t| Time.at(t) }
[2020-10-26 14:00:00 +1100,
2020-10-26 14:15:00 +1100,
2020-10-26 14:30:00 +1100,
2020-10-26 14:45:00 +1100,
2020-10-26 15:00:00 +1100,
2020-10-26 15:15:00 +1100,
2020-10-26 15:30:00 +1100,
2020-10-26 15:45:00 +1100,
2020-10-26 16:00:00 +1100,
2020-10-26 16:15:00 +1100,
2020-10-26 16:30:00 +1100,
2020-10-26 16:45:00 +1100,
2020-10-26 17:00:00 +1100
]
I want to exclude time which's not available. for eg:
2:30 to 3pm
3:15 to 4pm
any pretty way to fix this?
Upvotes: 1
Views: 79
Reputation: 3371
Not sure this counts as pretty but ...
interval = 15.minutes
start_time = '2:00 pm'.to_time
end_time = '5:00 pm'.to_time
taken = [
'2:30 pm'...'3:00 pm',
'3:15 pm'...'4:00 pm'
]
def slots(start_time, end_time, interval)
(start_time.to_i..end_time.to_i).
to_a.
in_groups_of(interval).
collect(&:first).
collect { |t| Time.at(t) }
end
def taken_slots(interval, taken)
taken.collect { |r|
slots(
r.begin.to_time,
r.end.to_time - (r.exclude_end? ? interval : 0),
interval
)
}.flatten
end
def available_slots(start_time, end_time, interval, taken)
slots(start_time, end_time, interval) - taken_slots(interval, taken)
end
available_slots(start_time, end_time, interval, taken)
gives
[
2020-10-26 14:00:00 +0000,
2020-10-26 14:15:00 +0000,
2020-10-26 15:00:00 +0000,
2020-10-26 16:00:00 +0000,
2020-10-26 16:15:00 +0000,
2020-10-26 16:30:00 +0000,
2020-10-26 16:45:00 +0000,
2020-10-26 17:00:00 +0000
]
I think if you needed to make slots faster the following miiiiight help (not tested though, and not sure what different values for interval might do)...
def slots(start_time, end_time, interval)
((start_time.to_i/interval)..(end_time.to_i/interval)).
to_a.
collect { |t| Time.at(t * interval) }
end
Edit:
The above faster slots seems to behave differently for different start and end times to how your original would, so maybe ignore that.
(example:)
interval = 15.minutes
start_time = '2:01 pm'.to_time
end_time = '5:00 pm'.to_time
def slots(start_time, end_time, interval)
(start_time.to_i..end_time.to_i).
to_a.
in_groups_of(interval).
collect(&:first).
collect { |t| Time.at(t) }
end
def slots_f(start_time, end_time, interval)
((start_time.to_i/interval)..(end_time.to_i/interval)).
to_a.
collect { |t| Time.at(t * interval) }
end
slots(start_time, end_time, interval) =>
[
2020-10-26 14:01:00 +0000,
2020-10-26 14:16:00 +0000,
2020-10-26 14:31:00 +0000,
2020-10-26 14:46:00 +0000,
2020-10-26 15:01:00 +0000,
2020-10-26 15:16:00 +0000,
2020-10-26 15:31:00 +0000,
2020-10-26 15:46:00 +0000,
2020-10-26 16:01:00 +0000,
2020-10-26 16:16:00 +0000,
2020-10-26 16:31:00 +0000,
2020-10-26 16:46:00 +0000
]
slots_f(start_time, end_time, interval) =>
[
2020-10-26 14:00:00 +0000,
2020-10-26 14:15:00 +0000,
2020-10-26 14:30:00 +0000,
2020-10-26 14:45:00 +0000,
2020-10-26 15:00:00 +0000,
2020-10-26 15:15:00 +0000,
2020-10-26 15:30:00 +0000,
2020-10-26 15:45:00 +0000,
2020-10-26 16:00:00 +0000,
2020-10-26 16:15:00 +0000,
2020-10-26 16:30:00 +0000,
2020-10-26 16:45:00 +0000,
2020-10-26 17:00:00 +0000
]
Upvotes: 1