据我了解,您将获得一个数组arr,其中包含太平洋标准时间区域内就寝时间的 UTC 时间。您希望计算平均就寝时间。
代码
def avg_bedtime(arr)
avg = Time.at(arr.reduce(0) do |t,s|
lt = Time.parse(s).localtime("-08:00")
t + Time.new(2000, 1, (lt.hour < 12) ? 2 : 1, lt.hour, lt.min, lt.sec, "-08:00").to_f
end/arr.size)
"%d:%d:%d" % [avg.hour, avg.min, avg.sec]
end
示例
arr = ["2015-12-10 08:58:24 UTC", "2015-12-09 03:35:28 UTC",
"2015-12-08 06:32:26 UTC", "2015-12-07 01:43:28 UTC",
"2015-12-05 07:49:30 UTC", "2015-12-04 07:02:30 UTC"]
我第一次改变了这个数组,让它更有趣。
avg_bedtime(arr)
#=> "21:56:57"
说明
让我们首先将这些字符串转换为时间对象:
utc = arr.map { |s| Time.parse(s) }
#=> [2015-12-10 08:58:24 UTC, 2015-12-09 03:35:28 UTC, 2015-12-08 06:32:26 UTC,
# 2015-12-07 01:43:28 UTC, 2015-12-05 07:49:30 UTC, 2015-12-04 07:02:30 UTC]
回顾 PST 比 UTC 晚 8 小时,我们可以使用 Time.localtime 转换为 PST:
pst = utc.map { |t| t.localtime("-08:00") }
#=> [2015-12-10 00:58:24 -0800, 2015-12-08 19:35:28 -0800,
# 2015-12-07 22:32:26 -0800, 2015-12-06 17:43:28 -0800,
# 2015-12-04 23:49:30 -0800, 2015-12-03 23:02:30 -0800]
我将把中午之前的就寝时间称为“晚”就寝时间,将当天晚些时候的就寝时间称为“早”就寝时间。 (这当然是任意的。例如,如果其中一些人是轮班工人,这可能是一个问题。)如您所见,pst 的第一个元素是晚睡时间,所有其他人都是早睡时间。
我现在将这些时间对象转换为具有相同时间但日期不同的时间对象。早睡对象将被分配一个任意日期(例如,January 1, 2000),晚睡对象将被分配一天后(January 2, 2000):
adj = pst.map { |t| Time.new(2000, 1, (t.hour < 12) ? 2 : 1, t.hour, t.min, t.sec, "-08:00") }
#=> [2000-01-02 00:58:24 -0800, 2000-01-01 19:35:28 -0800, 2000-01-01 22:32:26 -0800,
# 2000-01-01 17:43:28 -0800, 2000-01-01 23:49:30 -0800, 2000-01-01 23:02:30 -0800]
我们现在可以将时间对象转换为自纪元以来的秒数:
secs = adj.map { |t| t.to_f }
#=> [946803504.0, 946784128.0, 946794746.0, 946777408.0, 946799370.0, 946796550.0]
计算平均值:
avg = secs.reduce(:+)/arr.size
#=> 946792617.6666666
转换回 PST 区域的时间对象:
tavg = Time.at(avg)
#=> 2000-01-01 21:56:57 -0800
最后,提取一天中的时间:
"%d:%d:%d" % [tavg.hour, tavg.min, tavg.sec]
# "21:56:57