Castle and Riders

Date and Time Calculations in Rails

Calculating dates and times has always been a challenge for programmers. How many days until the next New Years Eve party (oh, did you forget 2008 is a leap year)? How long ago was the last backup (convert that to GMT, please)? What day of the week is 19 days, 42 hours, and 374 minutes from now (and how many milliseconds is that again)? And don’t even get me started on Y2K!

Almost all programming languages or frameworks provide some facilities for date and time calculations, but they often amount to instantiating multiple date objects and calling obscure methods. Many inexperienced coders end up rolling their own, either out of ignorance or due to the sheer complexity of existing date/time libraries.

Get on Rails Time

Due to Ruby’s inherent “everything is an object” design, the ActiveSupport libraries in Rails makes date and time calculations, if not trivial, at least radically easier. Let’s take a look at some examples — you can follow along by firing up an irb console for your favorite Rails app, like so:

cd /path/to/your/favorite/rails/app
script/console

Now type this in the irb shell:

>> 15.minutes.ago

You should see something like this:

=> Tue Jan 01 12:17:51 -0600 2008

Very nice! “15.minutes.ago” is functionally equivalent to:

Time.now.advance(:minutes => -15)

But as you can see, the former is much easier to read than the latter.

Rails Time Calculations

Time calculations in Rails are just as easy. For example:

>> (19.days + 42.hours + 374.minutes).seconds.from_now
=> Tue Jan 22 13:02:06 -0600 2008

For convenience, Rails automatically converts everything to seconds, which means I can chain the seconds() and from_now() methods to get the exact date and time in the future.

Simple Time Zone Adjustments

Although time zone conversions are inherently nasty, Rails handles them as smoothly as possible. Say, for instance, I want to convert a time value into GMT. First, I would set up a new time_zone instance, like so:

>> time_zone = TimeZone.new(0)
=> #<timezone :0x23bbaf8 @utc_offset=0, @name="Casablanca">

This creates a time zone object with an offset of zero (in Casablanca, no less). Next, I would pass a time to the adjust() method on that time_zone:

>> time_zone.adjust(15.minutes.ago)
=> Tue Jan 01 18:51:16 -0600 2008

There you have it — date and time calculations, including time zone adjustments, that won’t give you a headache!

Posted on January 1st, 2008 in the Rails category | Permalink
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

You must be logged in to post a comment.