【问题标题】:Iterating between two DateTimes, with a one hour step在两个 DateTime 之间迭代,步长为一小时
【发布时间】:2013-01-28 03:51:44
【问题描述】:

我正在寻找一种有效的方法,在 Ruby 1.9.x/Rails 3.2.x 中,以一小时的步长在两个 DateTime 对象之间进行迭代。

('2013-01-01'.to_datetime .. '2013-02-01'.to_datetime).step(1.hour) do |date|
   ...
end

我知道这个问题是 1.hour 只是秒数,但我尝试将其转换为 DateTime 对象并将其用作步骤也不起作用。

我查看了“Beware of Ruby Sugar”。它在底部附近提到 DateTime 有一个直接的step 方法。我通过在 DateTime 对象上运行 methods 确认了这一点,但我在 Ruby 或 Rails 的文档中都找不到关于 step 的任何文档。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    与我在“How do I return an array of days and hours from a range?”中的回答类似,诀窍是使用to_i 处理自纪元以来的秒数:

    ('2013-01-01'.to_datetime.to_i .. '2013-02-01'.to_datetime.to_i).step(1.hour) do |date|
      puts Time.at(date)
    end
    

    请注意,Time.at() 使用您的本地时区进行转换,因此您可能希望使用 Time.at(date).utc 指定 UTC

    【讨论】:

    • 此解决方案适用于1.hour1.day,但不适用于1.month。因为1.month 在 Rails 中总是 30 天。
    • 这不太对。 1.month 单独为 2592000 秒,但是(在 Rails 中)当结合日期和加/减时,x.months 实际上正确支持月份。以上可能无济于事,但请记住这一点。因此,要执行上述操作,您不能真正使用数组方法,而是使用 while 循环。阿拉:ruby date = DateTime.parse("2013-01-01"); finish = DateTime.parse("2015-02-01"); while(date < finish) do; puts Time.at(date); date += 1.month; end;
    • 对于需要四舍五入到小时的任何人,请参阅here
    【解决方案2】:

    也许迟到了,但你可以不用 Rails 来做,例如按小时计算:

    Ruby 2.1.0

    require 'time' 
    
    hour_step = (1.to_f/24)
    
    date_time = DateTime.new(2015,4,1,00,00)
    date_time_limit = DateTime.new(2015,4,1,6,00)
    
    date_time.step(date_time_limit,hour_step).each{|e| puts e}
    
    2015-04-01T00:00:00+00:00
    2015-04-01T01:00:00+00:00
    2015-04-01T02:00:00+00:00
    2015-04-01T03:00:00+00:00
    2015-04-01T04:00:00+00:00
    2015-04-01T05:00:00+00:00
    2015-04-01T06:00:00+00:00
    

    或分钟:

    #one_minute_step = (1.to_f/24/60)
    
    fifteen_minutes_step = (1.to_f/24/4)
    
    date_time = DateTime.new(2015,4,1,00,00)
    date_time_limit = DateTime.new(2015,4,1,00,59)
    
    date_time.step(date_time_limit,fifteen_minutes_step).each{|e| puts e}
    
    2015-04-01T00:00:00+00:00
    2015-04-01T00:15:00+00:00
    2015-04-01T00:30:00+00:00
    2015-04-01T00:45:00+00:00
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      这是我最近想出的一些东西:

      require 'active_support/all'
      
      def enumerate_hours(start, end_)
        Enumerator.new { |y| loop { y.yield start; start += 1.hour } }.take_while { |d| d < end_ }
      end
      
      enumerate_hours(DateTime.now.utc, DateTime.now.utc + 1.day)
      # returns [Wed, 20 Aug 2014 21:40:46 +0000, Wed, 20 Aug 2014 22:40:46 +0000, Wed, 20 Aug 2014 23:40:46 +0000, Thu, 21 Aug 2014 00:40:46 +0000, Thu, 21 Aug 2014 01:40:46 +0000, Thu, 21 Aug 2014 02:40:46 +0000, Thu, 21 Aug 2014 03:40:46 +0000, Thu, 21 Aug 2014 04:40:46 +0000, Thu, 21 Aug 2014 05:40:46 +0000, Thu, 21 Aug 2014 06:40:46 +0000, Thu, 21 Aug 2014 07:40:46 +0000, Thu, 21 Aug 2014 08:40:46 +0000, Thu, 21 Aug 2014 09:40:46 +0000, Thu, 21 Aug 2014 10:40:46 +0000, Thu, 21 Aug 2014 11:40:46 +0000, Thu, 21 Aug 2014 12:40:46 +0000, Thu, 21 Aug 2014 13:40:46 +0000, Thu, 21 Aug 2014 14:40:46 +0000, Thu, 21 Aug 2014 15:40:46 +0000, Thu, 21 Aug 2014 16:40:46 +0000, Thu, 21 Aug 2014 17:40:46 +0000, Thu, 21 Aug 2014 18:40:46 +0000, Thu, 21 Aug 2014 19:40:46 +0000, Thu, 21 Aug 2014 20:40:46 +0000, Thu, 21 Aug 2014 21:40:46 +0000] 
      

      【讨论】:

        【解决方案4】:

        我不完全确定这是否会有所帮助,但请查看此堆栈溢出页面,问题似乎相似。

        calculate difference in time in days, hours and minutes

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-04
          • 2021-08-18
          • 1970-01-01
          • 2021-11-18
          • 2011-10-10
          • 1970-01-01
          相关资源
          最近更新 更多