在两个DateTime之间迭代,步长为1小时

Bri*_*ian 32 ruby ruby-on-rails ruby-on-rails-3

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

('2013-01-01'.to_datetime .. '2013-02-01'.to_datetime).step(1.hour) do |date|
   ...
end
Run Code Online (Sandbox Code Playgroud)

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

我看着" 小心红宝石糖 ".在底部附近提到DateTime有一个直接的step方法.我通过methods在DateTime对象上运行来确认这一点,但是step在Ruby或Rails的文档中我找不到DateTime中的任何文档.

Ali*_*ael 56

类似于我在" 如何从一个范围返回一个天数和小时数组? "中的回答,诀窍是使用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
Run Code Online (Sandbox Code Playgroud)

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

  • 那不太对劲.1.month在隔离是2592000秒但是(在Rails中)当与日期和加法/减法相结合时,x.months实际上正确地支持了几个月.可能没有上述帮助,但要记住这一点.所以要做到这一点,你不能真正做阵列方法,而是采用while循环.Ala:```ruby date = DateTime.parse("2013-01-01"); finish = DateTime.parse("2015-02-01"); 而(日期<完成)做; 把Time.at(日期); 日期+ = 1.月; 结束; ``` (2认同)

Jua*_*ias 12

也许迟到了,你可以在没有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
Run Code Online (Sandbox Code Playgroud)

或分钟:

#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
Run Code Online (Sandbox Code Playgroud)

我希望它有所帮助.


Ian*_*mel 5

这是我最近想到的:

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] 
Run Code Online (Sandbox Code Playgroud)