Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating between two DateTimes, with a one hour step

I'm looking for an efficient way, in Ruby 1.9.x/Rails 3.2.x, to iterate between two DateTime objects, with a one-hour step.

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

I understand that an issue with this is that 1.hour is just the number of seconds, but my attempts to convert that to a DateTime object and use that as the step doesn't work either.

I looked at "Beware of Ruby Sugar". It mentions, near the bottom, that DateTime has a direct step method. I confirmed this by running methods on a DateTime object, but I cannot find any documentation on step in DateTime, in either Ruby's or Rails' documents.

like image 665
Brian Avatar asked Jan 28 '13 03:01

Brian


People also ask

How do I iterate between two dates in Python?

Using pandas to Iterate through a range of dates We can use the date_range() function method that is available in pandas. It is used to return a fixed frequency DatetimeIndex.

How do I loop through a date range?

One way to loop through a date range with JavaScript is to use a while loop. We can create variables for the start and end dates. Then we can increment the start date until it reaches the end date. We have the start and end variables with the start and end date respectively.


2 Answers

Similar to my answer in "How do I return an array of days and hours from a range?", the trick is to use to_i to work with seconds since the epoch:

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

Note that Time.at() converts using your local time zone, so you may want to specify UTC by using Time.at(date).utc

like image 103
Alistair A. Israel Avatar answered Sep 20 '22 17:09

Alistair A. Israel


Maybe late but, you can do it without Rails, for example to step with hours:

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 

Or minutes:

#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 

I hope it helps.

like image 24
Matias Avatar answered Sep 22 '22 17:09

Matias