-
-
Save campbell/0b30034d3f1e56fb4add to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'time' | |
TWELVE_HOURS = 12*60*60 | |
TWENTYFOUR_HOURS = TWELVE_HOURS*2 | |
def average_time_of_day(times) | |
# Since all times are relative, we don't know if the AM times occur before/after the PM times. | |
# We'll make an assumption that all times are somewhat related and thus should occur at about the | |
# same time, so we will choose start and end times that create the smallest possible time window. | |
# To do this, we will calculate the total time range with the AM times occurring before the PM times, | |
# then we'll compare this to the time range when the AM times occur after the PM times. | |
# | |
# If the AM times occur first, then the time window is the maximum PM time minus the minimum AM time. | |
# If the AM times occur after the PM times, then the time window is the maximum AM time plus 24 hours | |
# and minus the minimum PM time, eg. | |
# | |
# should_we_shift_the_AM_times = ( PM_MAX_TIME - AM_MAX_TIME ) < ( (AM_MIN_TIME+24) - PM_MIN_TIME) | |
# | |
# Of course, this only applies if we have both AM and PM times.... | |
midnight = Time.parse('12:00am') # Midnight today, needed since all times are relative | |
# Get each time relative to midnight today (since the input times are relative) | |
times = times.collect { |t| Time.parse(t)-midnight } # Convert the original array into relative times | |
am_times, pm_times = times.partition { |t| t < TWELVE_HOURS } | |
# Adjust any AM times by 24 hours if that makes the total time window smaller | |
if ( !am_times.empty? && !pm_times.empty? && (pm_times.max-am_times.min) > (am_times.max-pm_times.min+24*60*60) ) | |
am_times.each_index { |t| am_times[t] += TWENTYFOUR_HOURS } | |
times = pm_times + am_times | |
end | |
# Uncomment the next line to see the times for the selected shortest time window | |
# print "Debug: Time range: #{Time.at(times.min)+midnight.to_i} to #{Time.at(times.max)+midnight.to_i}\n" | |
# Calculate the average - we must add the relative average time to the baseline midnight time so we can | |
# get the correct absolute time | |
sum = times.inject(0) { |s,i| s+i } | |
average_time = Time.at(sum.to_f/times.length)+midnight.to_i # TO_I needed for time addition operator | |
average_time.strftime('%I:%M%p').downcase | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment