27

I'm trying to step every N days between two dates. I tried the following code but is wasn't working because startDate and endDate are ActiveSupport::TimeWithZone objects and not DateTime objects like I thought.

startDate.step(endDate, step=7) { |d| puts d.to_s}
  min.step(max, step=stepInt){ |d|
  puts d.to_s  
}

How do I covert the TimeWithZone object to a DateTime?

Brig
  • 10,211
  • 12
  • 47
  • 71

2 Answers2

40

I thought it might be useful to update this answer as I was searching this up recently. The easiest way to achieve this conversion is using the .to_datetime() function.

e.g.

5.hours.from_now.class              # => ActiveSupport::TimeWithZone
5.hours.from_now.to_datetime.class  # => DateTime

ref: http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html#method-i-to_datetime

Chris A James
  • 421
  • 1
  • 4
  • 6
19

DateTime is an old class which you generally want to avoid using. Time and Date are the two you want to be using. ActiveSupport::TimeWithZone acts like Time.

For stepping over dates you probably want to deal with Date objects. You can convert a Time (or ActiveSupport::TimeWithZone) into a Date with Time#to_date:

from.to_date.step(to.to_date, 7) { |d| puts d.to_s }
Jason Weathered
  • 7,762
  • 2
  • 41
  • 37
  • 6
    http://stackoverflow.com/questions/1261329/whats-the-difference-between-datetime-and-time-in-ruby recommends DateTime as the best way to handle your Dates! – Andre Schweighofer Nov 25 '11 at 11:33
  • 17
    DateTime is a Ruby class. ActiveSupport::TimeWithZones is Rails. So saying that it's "old" and you should avoid it, isn't accurate. See ChrisJ's answer for a better response. – IAmNaN Apr 18 '13 at 19:28
  • Postgres' 'Timestamp' converts to Rails' TimeWithZone, with is not at all friendly to display, so using DateTime is very often better, and here 4 years later it is still not old. – Ian M Sep 13 '14 at 18:07
  • 1
    Why do I want to avoid using DateTime? DateTime is an aggregate of Date and Time. So if I need date plus time, I should use DateTime, no? Although it does appear that Time gives you date too. Plus with Time, you can use zone e.g. Time.zone.now => Tue, 02 Jun 2015 14:01:58 EDT -04:00, which gives you date and time and timezone. – Donato Jun 02 '15 at 18:02
  • @Donato You want to avoid using DateTime because Time.zone can do everything DateTime can do, and is easier to always remember to use than remembering adding a `.in_time_zone` after your datetimes specifically. More examples and reasoning here: http://danilenko.org/2012/7/6/rails_timezones/ – Magne Aug 29 '17 at 07:54
  • @IanM TimeWithZone can be displayed exactly the same as DateTime, if you want. By default it displays no different than merely having ie. `CEST +02:00` instead of `+0200` at the end.. – Magne Aug 29 '17 at 07:57