我想在Ruby中列出日期时间列表,然后计算之间的天数,然后平均这些日期。它是否正确?有没有更短的方法来做到这一点?
dates = ["2012-08-05 00:00:00 UTC", "2012-06-17 00:00:00 UTC", "2012-06-15 00:00:00 UTC", "2011-06-06 00:00:00 UTC"]
difference = Array.new
dates.each_with_index do |date, index|
if index != 0
difference << date.to_date - dates[index - 1].to_date
end
end
avg = difference.inject{ |sum, el| sum + el }.to_f / arr.size
然后以天的格式输出它吗?
如果你喜欢我可以给我一个Rails版本,因为我会从模型领域中提取日期时间。
答案 0 :(得分:4)
我认为你有一个一个接一个的问题。如果您在n
中有dates
个值,那么连续对之间会有n-1
个差异,因此您的avg
应为:
avg = difference.inject{ |sum, el| sum + el }.to_f / (arr.size - 1)
而你的inject
只是一个冗长的说法inject(:+)
,所以你可以说:
avg = difference.inject(:+).to_f / (arr.size - 1)
无论如何,您可以使用map
和each_cons
来让它更好一点:
dates.map(&:to_date).each_cons(2).map { |d1, d2| d1 - d2 }.inject(:+) / (dates.length - 1)
首先,我们可以使用map(&:to_date)
在一次传递中将所有内容转换为日期,而不是在每次需要日期而不是字符串时进行转换。然后each_cons(2)
以连续对的方式迭代数组(即[1,2,3,4]
被迭代为[[1,2], [2,3], [3,4]]
)。然后是一个简单的map
来获取对和inject(:+)
之间的差异,将它们全部添加起来。
以上内容会为您留下Rational
,但如果您需要浮点数或整数值,则可以to_f
或to_i
。
答案 1 :(得分:1)
我可能会离开这里,但我认为这应该有效:
require 'date'
dates.map!{|x| Date.parse(x)}.sort!
p (dates.last - dates.first)/(dates.size - 1) #=> (142/1)
还是更漂亮?
first, last = dates.map!{ |x| Date.parse(x) }.minmax
p (last - first)/(dates.size - 1) #=> (142/1)
答案 2 :(得分:0)
如下:
def room_expiry_date_in_days(room)
a=room.expiry_date.strftime("%Y-%m-%d")
b=room.created_at.strftime("%Y-%m-%d")
a=Date.parse(a)
b=Date.parse(b)
days=(a-b).to_i
return "#{pluralize(days, 'day',"days")} left"
end
或者如果我理解不正确,那么总会有:
span_secs = Foo.maximum(:created_at) - Foo.minimum(:created_at)
avg_secs = span_secs / (Foo.count - 1)
avg_days = avg_secs / (24 * 60 * 60)