secret
Created

  • Download Gist
joshbaxley.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
require "parsedate"
include ParseDate
 
def average_time_of_day(times_array)
#Reduce the string array to an array of hours followed by seconds
times_array.collect! { |i| parsedate(i) }
times_array.flatten!
times_array.compact!
#get length of new array
n = times_array.length
#get array indices of hours (even) and minutes (odd)
hours_indices = (0..n).find_all { |i| i%2 == 0 }
minutes_indices = (0..n).find_all { |i| i%2 == 1 }
#pick a starting point
epoch = Time.at(0)
#set up empty array that will hold our times as numbers that we can average
t = []
#iterate through hours and minutes and make them universal time integers
(n/2).times do |i|
t<<Time.local(epoch.year+1,epoch.month,epoch.day,times_array[hours_indices[i]],times_array[minutes_indices[i]],0).to_i
end
#now we need to make sure the times are sufficiently close to each other
#so we have a meaningful average. If the times differ by 12 hours, we need to
#adjust the AM times so they fall on the day following the PM times
if (Time.at(t.max).hour - Time.at(t.min).hour) > 12
t.collect! { |i|
if Time.at(i).hour.to_i < 12
(i + 60*60*24)
else
i
end
}
end
#average our times
avg = (t.inject { |sum,k| sum+k }) / t.length
#output!
Time.at(avg).strftime("%I:%M%p").downcase![/[1]?[0-9]:[0-5][0-9][\w]{2}/]
end
 
##test cases
#this should be 12:01pm
#puts average_time_of_day(["11:51am", "11:56am", "12:01pm", "12:06pm", "12:11pm"])
#this should be 12:01am
#puts average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"])
#this should be 6:51am
#puts average_time_of_day(["6:41am", "6:51am", "7:01am"])

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.