Question

I'm writing a Rails app that will allow users to input what time of day they finish a task.

I am storing the times as Time objects, and I need a way to get the average time of day the task was completed for a user.

How can I accomplish this?

My attempt with Малъ Скрылевъ's answer

@deliveries = Delivery.all


times = Array.new
@deliveries.each do |d|
  times.push(d.time)
end
puts times # gives me [2000-01-01 06:15:00 UTC, 2000-01-01 07:18:00 UTC]
unless times.empty?
  @avg = Time.at(times.map(&:to_i).reduce(:+) / times.size)
end
puts @avg #gives me 1999-12-31 23:46:30 -0700
Était-ce utile?

La solution 2

You can calculate avg by Time objects (they can be in different days). Something like this should work.

deliveries_at = @deliveries.map { |d| d.time.hour * 3600 + d.time.min * 60 + t.sec }
avg = deliveries_at.inject(:+) / deliveries_at.count
avg_hour = avg / 3600
avg_minute = (avg % 3600) / 60
avg_second = avg % 60

First line collect seconds-from-the-start-of-the-day for each delivery. Second line calculate average (in seconds) and last three lines turn it into hour/minute/second.

Autres conseils

Just you can use mathematic equations and statement on the Time object represented as Integer:

times = [ Time.now, Time.now ]
Time.at(times.map(&:to_i).reduce(:+) / times.size)

Examples

And the same for the specific time array:

  1. First:

    times = ["2000-01-01 08:13:00 UTC", "2000-01-01 18:14:00 UTC", "2000-01-01 16:55:00 UTC", "2000-01-01 23:53:00 UTC", "2000-01-01 00:56:00 UTC", "2000-01-01 02:57:00 UTC", "2000-01-01 00:01:00 UTC"].map {|t| Time.parse(t) }
    Time.at(times.map(&:to_i).reduce(:+) / times.size)
    # => 2000-01-01 13:09:51 +0300
    
  2. Second:

    times = ['2000-01-01 06:15:00 UTC', '2000-01-01 07:18:00 UTC'].map {|t|Time.parse(t)}
    # => [2000-01-01 06:15:00 UTC, 2000-01-01 07:18:00 UTC] 
    Time.at(times.map(&:to_i).reduce(:+) / times.size)
    # => 2000-01-01 09:46:30 +0300 
    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top