有没有一种方法可以在Ruby中迭代一个时间范围,并设置增量?以下是我想做的一个想法:
for hour in (start_time..end_time, hour) hour #=> Time object set to hour end
字符串您可以遍历Time对象,但它会在两个对象之间每秒返回一次。我真正需要的是一种设置偏移量或增量(如分钟、小时等)的方法这是Ruby内置的吗,还是有一个不错的插件可用?
mfuanj7w1#
在1.9之前,可以使用Range#step:
Range#step
(start_time..end_time).step(3600) do |hour| # ... end
字符串但是,这种策略非常慢,因为它会调用Time#succ 3600次。相反,正如dolzenko在his answer中指出的那样,更有效的解决方案是使用一个简单的循环:
Time#succ
hour = start_time while hour < end_time # ... hour += 3600 end
型如果你使用Rails,你可以用1.hour代替3600,它的可读性更好。
1.hour
inn6fuwd2#
如果你的start_time和end_time实际上是Time类的示例,那么使用Range#step的解决方案将是非常低效的,因为它将在这个范围内用Time#succ每秒迭代一次。如果你把你的时间转换成整数,简单的加法将被使用,但这样你最终会得到这样的结果:
start_time
end_time
Time
(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
型
dzjeubhm3#
Range#step方法在这种情况下非常慢。使用开始..end while,正如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
型如果在轨道中。
bkhjykvo4#
以下是每种情况的通用函数:
def split_time_by_periods(start_time, end_time, time_step) return to_enum(:split_time_by_periods, start_time, end_time, time_step) unless block_given? start_time = start_time.to_i end_time = end_time.to_i current_time = start_time while current_time < end_time period_end = [current_time + time_step, end_time].min yield(Time.at(current_time).utc, Time.at(period_end).utc) current_time += time_step end end
字符串使用方法:
split_time_by_periods(Time.now, Time.now + 1.hour + 30.minutes, 1.hour).to_a # => [[2023-07-26 08:00:26 UTC, 2023-07-26 09:00:26 UTC], [2023-07-26 09:00:26 UTC, 2023-07-26 09:30:26 UTC]] split_time_by_periods(Time.now, Time.now + 1.day, 5.hours) do |period_start, period_end| # ... end split_time_by_periods(Time.now, Time.now + 1.day, 5.hours).map do |period_start, period_end| # ... end
4条答案
按热度按时间mfuanj7w1#
在1.9之前,可以使用
Range#step
:字符串
但是,这种策略非常慢,因为它会调用
Time#succ
3600次。相反,正如dolzenko在his answer中指出的那样,更有效的解决方案是使用一个简单的循环:型
如果你使用Rails,你可以用
1.hour
代替3600,它的可读性更好。inn6fuwd2#
如果你的
start_time
和end_time
实际上是Time
类的示例,那么使用Range#step
的解决方案将是非常低效的,因为它将在这个范围内用Time#succ
每秒迭代一次。如果你把你的时间转换成整数,简单的加法将被使用,但这样你最终会得到这样的结果:字符串
但是这也可以用更简单和更有效的(即,没有所有类型转换)循环:
型
dzjeubhm3#
Range#step方法在这种情况下非常慢。使用开始..end while,正如dolzenko在这里发布的那样。
您可以定义一个新方法:
字符串
那么,
型
如果在轨道中。
bkhjykvo4#
以下是每种情况的通用函数:
字符串
使用方法:
型