Iterate over Ruby Time object with delta

前端 未结 3 2081
攒了一身酷
攒了一身酷 2020-12-01 14:06

Is there a way to iterate over a Time range in Ruby, and set the delta?

Here is an idea of what I would like to do:

for hour in (start_time..end_time         


        
相关标签:
3条回答
  • 2020-12-01 14:34

    If your start_time and end_time are actually instances of Time class then the solution with using the Range#step would be extremely inefficient since it would iterate over every second in this range with Time#succ. If you convert your times to integers the simple addition will be used but this way you will end up with something like:

    (start_time.to_i..end_time.to_i).step(3600) do |hour|
      hour = Time.at(hour)     
      # ...
    end
    

    But this also can be done with simpler and more efficient (i.e. without all the type conversions) loop:

    hour = start_time
    begin
      # ...      
    end while (hour += 3600) < end_time
    
    0 讨论(0)
  • 2020-12-01 14:37

    Prior to 1.9, you could use Range#step:

    (start_time..end_time).step(3600) do |hour|
      # ...
    end
    

    However, this strategy is quite slow since it would call Time#succ 3600 times. Instead, as pointed out by dolzenko in his answer, a more efficient solution is to use a simple loop:

    hour = start_time
    while hour < end_time
      # ...
      hour += 3600
    end
    

    If you're using Rails you can replace 3600 with 1.hour, which is significantly more readable.

    0 讨论(0)
  • 2020-12-01 14:39

    Range#step method is very slow in this case. Use begin..end while, as dolzenko posted here.

    You can define a new method:

      def time_iterate(start_time, end_time, step, &block)
        begin
          yield(start_time)
        end while (start_time += step) <= end_time
      end
    

    then,

    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
    

    if in rails.

    0 讨论(0)
提交回复
热议问题