Skip to content

Instantly share code, notes, and snippets.

@robisonsantos
Created October 9, 2009 03:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robisonsantos/fbce018487644b33eb74 to your computer and use it in GitHub Desktop.
Save robisonsantos/fbce018487644b33eb74 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby -w
# Robison WR Santos
# Brazil
# rwrsantos@gmail.com
#
# This method calculates the average time given a list with all time values
# you want the count.
# It assumes that the first value on the list is the lesser value of it.
# By this assumption, it treats this value as the base to do all the computation
# and find the most probable average time of the passed list.
# How many seconds do we have in one day?
A_DAY = 24 * 60 * 60
def average_time_of_day(times_str)
# transforms all str_time into float time representation and store them into
# an array
times = times_str.map {|t| Time.parse(t).to_f}
# get the first element as a basis
base_time = times.delete_at(0)
# get all deltas between the current t time and the base time
# as Time.parse assumes the time from today, if the current time is lesser than
# the base time, we assume that it comes from the next day.
deltas = times.map {|t| t >= base_time ? t - base_time : (t + A_DAY) - base_time}
# sum all the deltas
deltas_sum = deltas.inject(0) {|s,d| s + d}
# calculate the average delta
average_delta = deltas_sum / (times.size + 1)
# calculate the average time by the sum of the average_delta and the base_time
Time.at(base_time + average_delta).strftime("%I:%M%p")
end
# tests
require 'test/unit'
class TestAverageTimeOfDay < Test::Unit::TestCase
def test_five_values_on_the_same_range
times_str = ['11:50pm','11:52pm','11:54pm','11:56pm','11:58pm']
assert_equal '11:54PM', average_time_of_day(times_str)
end
def test_four_values_on_the_same_range
times_str = ['11:50pm','11:52pm','11:54pm','11:56pm']
assert_equal '11:53PM', average_time_of_day(times_str)
end
def test_time_passes_from_midnight
times_str = ['11:51pm','11:56pm','12:01am','12:06am','12:11am']
assert_equal '12:01AM', average_time_of_day(times_str)
end
def test_time_passes_from_noon
times_str = ['11:51am','11:56am','12:01pm','12:06pm','12:11pm']
assert_equal '12:01PM', average_time_of_day(times_str)
end
def test_three_value_on_the_same_range
times_str = ['6:41am','6:51am','7:01am']
assert_equal '06:51AM', average_time_of_day(times_str)
end
def test_only_one_value_in_the_morning
times_str = ['6:41am']
assert_equal '06:41AM', average_time_of_day(times_str)
end
def test_only_one_value_in_the_afternoon
times_str = ['6:41pm']
assert_equal '06:41PM', average_time_of_day(times_str)
end
def test_twelve_hours_different_from_morning
times_str = ['6:41am','6:41pm']
assert_equal '12:41PM', average_time_of_day(times_str)
end
def test_twelve_hours_different_from_afternoon
times_str = ['6:41pm','6:41am']
assert_equal '12:41AM', average_time_of_day(times_str)
end
def test_mixed_time_post_midnight_with_the_lesser_value_before_midnight
times_str = ['11:10pm','11:15pm','12:03am','11:30pm','11:48pm']
assert_equal '11:33PM', average_time_of_day(times_str)
end
def test_mixed_time_post_midnight_with_the_lesser_value_after_midnight
times_str = ['12:03am','11:10pm','11:15pm','11:30pm','11:48pm']
assert_equal '06:45PM', average_time_of_day(times_str)
end
def test_all_values_the_same
times_str = ['11:10pm','11:10pm','11:10pm','11:10pm','11:10pm']
assert_equal '11:10PM', average_time_of_day(times_str)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment