有没有办法迭代Ruby中的时间范围,并设置delta?
以下是我想要做的事情:
for hour in (start_time..end_time, hour)
hour #=> Time object set to hour
end
您可以遍历Time对象,但它会在两者之间每秒返回一次。我真正需要的是一种设置偏移或增量(如分钟,小时等)的方法
这是内置于Ruby,还是有一个不错的插件?
答案 0 :(得分:55)
在1.9之前,您可以使用Range#step
:
(start_time..end_time).step(3600) do |hour|
# ...
end
然而,这种策略非常缓慢,因为它会调用Time#succ
3600次。代替,
正如dolzenko在his answer中所指出的,更有效的解决方案是使用一个简单的循环:
hour = start_time
while hour < end_time
# ...
hour += 3600
end
如果您正在使用Rails,则可以使用1.hour
替换3600,这显然更具可读性。
答案 1 :(得分:39)
如果您的start_time
和end_time
实际上是Time
类的实例,那么使用Range#step
的解决方案效率极低,因为它会在此每秒迭代一次范围Time#succ
。如果您将时间转换为整数,则会使用简单的加法,但这样您最终会得到类似的结果:
(start_time.to_i..end_time.to_i).step(3600) do |hour|
hour = Time.at(hour)
# ...
end
但这也可以通过更简单,更高效(即没有所有类型转换)循环来完成:
hour = start_time
begin
# ...
end while (hour += 3600) < end_time
答案 2 :(得分:17)
在这种情况下,范围#step方法非常慢。使用begin..end,正如dolzenko在这里发布的那样。
您可以定义新方法:
def time_iterate(start_time, end_time, step, &block)
begin
yield(start_time)
end while (start_time += step) <= end_time
end
然后,
start_time = Time.parse("2010/1/1")
end_time = Time.parse("2010/1/31")
time_iterate(start_time, end_time, 1.hour) do |t|
puts t
end
如果在铁轨中。