Ruby on rails 在Ruby中迭代1个月需要15秒-什么';在Ruby中迭代时间间隔的最佳方法是什么?
如果我每小时重复一个月做一件事,使用Ruby on rails 在Ruby中迭代1个月需要15秒-什么';在Ruby中迭代时间间隔的最佳方法是什么?,ruby-on-rails,ruby,datetime,Ruby On Rails,Ruby,Datetime,如果我每小时重复一个月做一件事,使用Range#step大约需要14秒: bm = Benchmark.measure do (Time.now..(Time.now + 1.month)).step(1.hour) { |hour| puts hour.inspect } end puts bm => 14.750000 0.060000 14.810000 ( 14.907838) 那是因为它每[秒]迭代一次?从一小时开始,为每小时创建和迭代一系列时间的最佳方式是什么 ra
Range#step
大约需要14秒:
bm = Benchmark.measure do
(Time.now..(Time.now + 1.month)).step(1.hour) { |hour| puts hour.inspect }
end
puts bm
=> 14.750000 0.060000 14.810000 ( 14.907838)
那是因为它每[秒]迭代一次?从一小时开始,为每小时创建和迭代一系列时间的最佳方式是什么
range == [...Wed Feb 09 11:00:00 -0600 2011, Wed Feb 09 12:00:00 -0600 2011, ...]
注意:假设您在
1.月和1.小时期间需要activesupport
。此外,这会给你固定大小的月份(2592000秒),这限制了它的实用性。这可能是一种替代方法。至少看起来要快得多
bm = Benchmark.measure do
time = Time.now
while time < (Time.now + 1.month)
puts time.inspect
time += 1.hour
end
end
puts bm
=> 0.483000 0.000000 0.483000 ( 0.546000)
bm=Benchmark.measure do
时间=现在
时间<(time.now+1.month)
花时间检查
时间+=1.5小时
结束
结束
放置bm
=> 0.483000 0.000000 0.483000 ( 0.546000)
一个月的时间不是一个常数。您还必须处理夏令时等问题,以便快速、准确地按小时迭代一个月(或任何时间跨度):
bm = Benchmark.measure do
s_time = Time.local(2011,1,1)
e_time = Time.local(2011,2,1)
while(s_time < e_time)
puts s_time.inspect
s_time += 3600
end
end
puts bm
0.010000 0.000000 0.010000 ( 0.010531)
我写了一些东西,在rails中迭代了几天
def each_day(range, &block)
values = []
(range.first.to_i .. range.last.to_i).step(1.day) { |d| values << Time.at(d) }
return values unless block_given?
values.each { |val| yield(val) }
end
range = (Time.local(2012, 12, 31) .. Time.local(2013, 1, 1))
each_day(range) { |d| puts d.inspect }
def每天(范围和块)
值=[]
(range.first.to_i..range.last.to_i).步骤(1.day){d|valuesTime.parse
的工作方式与您想象的不同。Time.parse('2/1/2011'))#=>2011-01-02 00:00:00-0700
,是1月2日,而不是2月1日。parse
不知道我们在美国通常是如何进行MM/DD/yyyyy的。相反,如果使用DD/MM/YYYY,这是欧洲的标准。其后果是,您的基准时间比应该的时间要短得多,因为您没有迭代正确的小时数s、 我使用ruby 1.8.7时,这一过程持续了数小时。您对ruby 1.9的说法是正确的,但它已经发生了变化。示例已更改为使用ruby 1.9的帐户,正如预期的那样。1.hour
不是标准ruby。它通常需要Rails的ActiveSupport,因此您可能希望展示如何正确地要求它,因为它不是straight-forward在Rails 3+中有很好的观点,但由于它实际上在问题中被使用,我认为可能没有必要解释。很好的观点。我将在OP的问题的标签中添加Rails。我认为在Ruby 1.9.2中你不能以这种方式使用步骤。至少在这里,它抛出类型错误:不能从时间开始迭代。这是最惯用的方法我想是接近。
s_time += s_time.to_i % 3600
e_time -= e_time.to_i % 3600
def each_day(range, &block)
values = []
(range.first.to_i .. range.last.to_i).step(1.day) { |d| values << Time.at(d) }
return values unless block_given?
values.each { |val| yield(val) }
end
range = (Time.local(2012, 12, 31) .. Time.local(2013, 1, 1))
each_day(range) { |d| puts d.inspect }