Avdept
Avdept

Reputation: 2289

Count time within time range

I need to count amount of time in specified range. For example, I have range (let's call it peak hours) 12:00-14:00. And i have another range(visit time), that might change, for ex 9:00-15:00. How do I get intersected hours for these 2 ranges?

As result I would like to get something like: {peak_hours: 2, regular_hours: 4} Here peak_hours value is 2 as that many peak hours overlap with regular hours. And, regular_hours value is 4 as that many regular hours do not overlap with peak hours.

I'm kinda stuck with solution. I tried to use time ranges, but that didn't work for me. This is the code

peak_hours_range = Time.parse(peak_hour_start)..Time.parse(peak_hour_end)

session_range = visit_start..visit_end

inters = session_range.to_a & peak_hours_range.to_a

But this throws me type error

Upvotes: 1

Views: 271

Answers (2)

Wand Maker
Wand Maker

Reputation: 18762

Here is one way to do it, we find the total hours in both ranges included, and then remove the peak hours from it to get effective regular hours.

require "time"

peak_hour_start = "12:00"
peak_hour_end = "14:00"

regular_hour_start = "9:00"
regular_hour_end = "15:00"

ph = (Time.parse(peak_hour_start).hour...Time.parse(peak_hour_end).hour).to_a
#=> [12, 13]
rh = (Time.parse(regular_hour_start).hour...Time.parse(regular_hour_end).hour).to_a
#=> [9, 10, 11, 12, 13, 14]
total = (ph + rh).uniq
#=> [12, 13, 9, 10, 11, 14]
r = {peak_hours: (ph - rh).size, regular_hours: (total - ph).size}
#=> {:peak_hours=>2, :regular_hours=>4}

Upvotes: 1

T J
T J

Reputation: 1342

You can always try to find the intersection yourself.

inters = nil

intersection_min = [peak_hour_start, visit_start].max
intersection_max = [peak_hour_end, visit_end].min

if intersection_min < intersection_max
  inters = [intersection_min, intersection_max]
end

inters

Of course this can be cleaned up by extracting it out into it's own method.

Upvotes: 1

Related Questions