Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在Ruby中迭代1个月需要15秒-什么';在Ruby中迭代时间间隔的最佳方法是什么?_Ruby On Rails_Ruby_Datetime - Fatal编程技术网

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|values
Time.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 }