dcsimg

Date Handling in Rails Applications

Brief walkthru of capturing, storing, and displaying days with Ruby on Rails.

Date handling is one of the web’s inevitables. Almost any web application you write is going to include some form of date-bound hacking. Whether it’s capturing user input via a web form, calculating the difference between two times, or fetching data via a date range, time and the web are closely linked.

Luckily for us, Rails make handling dates and times, like everything else, fairly trivial; that is, once you have an idea of how everything works.

I recently rewrote the section of our admin site in Rails that handles the creation of back issues. Since I had to hunt all over the web for a complete package of documentation to finalize this small task I thought it might be a good idea to share my experience.

In the interest of time we’ll assume you have a Rails app up and running and have controllers and models in place that you’re looking to add date-handling code to.

Form Helpers

Let’s start with data capture via a simple web form. When storing a back issue in the database the most important data we need to capture is its print date. As far as our back issues are concerned, print date is just a month and a year. To accomplish this, Rails provides a few FormHelpers for picking dates that we’ll use in our view.

/app/view/back_issues/new.rhtml

<%= error_messages_for :back_issue %>
<% form_for :back_issue do |f| %>

Print Month: <%= select_month(Date.today, :field_name => "print_month") %> 

Print Year: <%= select_year(Date.today, :start_year => 1999, :field_name => "print_year") %>

<%= submit_tag value='Create Backissue' %>
<% end %>

select_month() and select_year() generate pulldown menus for picking the issue’s month and year.

Pay special attention the :field_name option. It’s not documented well in the Rails API proper and will come in handy when you need to change the name of these select boxes to something other than the default of date[month] and date[year]; necessary if you are using multiple instances of these helpers in a single form.

For still greater control over a date submitted via a form, you might want to take look at select_datetime, which provides a pulldown for each element of a timestamp. Or for something a little more user friendly, check out the really nice Protoype-based Calendar Date Select.

Storing the Data

There’s no real reason for us to store the values from these two fields in separate database columns. Rather we’ll use the month and year values to construct a date in the controller and store the result in a single datetime field called print_date.

/app/controllers/back_issue_controller.rb

class BackIssuesController < ApplicationController

  def new
    @back_issue = BackIssue.new(params[:back_issue])
    return unless request.post?
    @back_issue.print_date = Date.new(params[:date]['print_year'].to_i, params[:date]['print_month'].to_i)
    @back_issue.save!
    flash[:notice] = "New back issue created."
    redirect_to "/covers/new?bi=" + @back_issue.id.to_s

	# In the event our validations fail
    rescue ActiveRecord::RecordInvalid
      render :action => 'new'
  end

end

Ok, that should do it. Once we’ve created an instance of @back_issue with the parameters from the form, we have access to print_date and can give it a newly constructed datetime with Date.new().

Date.new() can take three parameters (year, month, day). We’re taking the default of 1 on the day parameter by not passing anything to the method. In this example, we’re really only concerned with the month and year so the default is fine.

In reality, the new() method on our BackIssuesController is actually a bit more complex than this– hence the params[:back_issue] — but for the sake of simplicity, we’re just showing how to push a new date into the publish_date column from pulldown menus.

The redirect_to in this case point to our cover upload form, but you can point it to whatever destination you like following a successful save!.

Manipulating Dates

We don’t actually need to modify the date after it’s submitted to our controller, but if we did, Ruby has a few operators for quickly adjusting a Date object.

Operator Function
+(n) Add n days to the date
-(n) Subtract n days to the date
>>(n) Add n months to the date
<<(n) Subtract n months to the date

Pretty simple stuff. To demonstrate, let’s take these operators for a spin on the console.

>> d = Date.new(2007, 8, 23)
=> #
>> d.to_s
=> "2007-08-23"
>> yesterday = d-1
=> #
>> yesterday.to_s
=> "2007-08-22"
>> tomorrow = d+1
=> #
>> tomorrow.to_s
=> "2007-08-24"
>> lastmonth = d<<1
=> #
>> lastmonth.to_s
=> "2007-07-23"
>> nextmonth = d>>1
=> #
>> nextmonth.to_s
=> "2007-09-23"

Displaying Dates

Alright, now that we’ve written our back issue date to the database, all that’s left to do is display it in a view. We probably don’t want to display the date formatted as it’s stored: ‘YYYY-MM-DD’. Rather we want something like the current back issue page that displays the full month name and the year. To accomplish this we’ll use strftime().

If you’re familiar with PHP’s date() method, strftime() is similar, you pass the method a format string that defines how you want the date output. The difference is that while you pass PHP’s date() both a format and a timestamp, strftime() is a method that operates on a Date object. And everything in Rails is an object.

Rails automatically knows to treat our datetime columns in the database as Date objects, so, after you’ve fetched the back issue data from the database in the controller, formatting the date in the view is as simple as:

<%= @back_issue.print_date.strftime('%B %Y') %>

Which will print something like “January 2007″ to the screen.

For a full list of format codes for strftime(), see the table below.

Format Meaning
%a The abbreviated weekday name (“Sun”)
%A The full weekday name (“Sunday”)
%b The abbreviated month name (“Jan”)
%B The full month name (“January”)
%c The preferred local date and time representation
%d Day of the month (01..31)
%H Hour of the day, 24-hour clock (00..23)
%I Hour of the day, 12-hour clock (01..12)
%j Day of the year (001..366)
%m Month of the year (01..12)
%M Minute of the hour (00..59)
%p Meridian indicator (“AM” or “PM”)
%S Second of the minute (00..60)
%U Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
%W Week number of the current year, starting with the first Monday as the first day of the first week (00..53)
%w Day of the week (Sunday is 0, 0..6)
%x Preferred representation for the date alone, no time
%X Preferred representation for the time alone, no date
%y Year without a century (00..99)
%Y Year with century
%Z Time zone name
%% Literal “%” character

Rails Magic Wishlist

And that’s about it. Not too difficult but it’s actually a little more work that I’d like to do. Frankly, I wish there was some Rails magic that did the date handling in the controller for me.

Creating a new date and casting parameters in the controller isn’t how I’d like this to function — ultimately it doesn’t strike me as terribly DRY. Rather, I would like to have the option of passing the form fields to the controller as back_issue[print_date_month] and back_issue[print_date_year] and have Rails realize that these are components of my print_date field and compile these elements into a date for me. But all-in-all the solution we have here is reasonably clean and maybe I can build some of that magic into a plugin or helper at a later date.

Comments on "Date Handling in Rails Applications"

Thanks guy, that was helpful

Reply

Thanks again for the article. Awesome.

Reply

Major thanks for the blog article.Really thank you!

Reply

Do you mind if I quote a few of your posts as long as I provide credit and sources back to your site? My blog site is in the very same niche as yours and my users would certainly benefit from a lot of the information you provide here. Please let me know if this alright with you. Thank you!

Reply

Please let me know if you’re looking for a article writer for your blog. You have some really great articles and I think I would be a good asset. If you ever want to take some of the load off, I’d really like to write some articles for your blog in exchange for a link back to mine. Please shoot me an e-mail if interested. Thank you!

Reply

I’ll gear this review to 2 types of people: current Zune owners who are considering an upgrade, and people trying to decide between a Zune and an iPod. (There are other players worth considering out there, like the Sony Walkman X, but I hope this gives you enough info to make an informed decision of the Zune vs players other than the iPod line as well.)

Reply

The Zune concentrates on being a Portable Media Player. Not a web browser. Not a game machine. Maybe in the future it’ll do even better in those areas, but for now it’s a fantastic way to organize and listen to your music and videos, and is without peer in that regard. The iPod’s strengths are its web browsing and apps. If those sound more compelling, perhaps it is your best choice.

Reply

I want to express my love for your generosity supporting men and women that have the need for help with this situation. Your special dedication to getting the message along appears to be pretty beneficial and have consistently empowered guys like me to realize their ambitions. Your interesting tutorial signifies this much a person like me and substantially more to my office colleagues. Many thanks; from all of us.

Reply

With havin so much written content do you ever run into any issues of plagorism or copyright infringement? My site has a lot of unique content I’ve either written myself or outsourced but it seems a lot of it is popping it up all over the web without my agreement. Do you know any solutions to help reduce content from being stolen? I’d definitely appreciate it.

Reply

I visited a lot of website but I conceive this one has something special in it in it

Reply

I simply wished to appreciate you once more. I am not sure what I would’ve sorted out in the absence of those tips discussed by you concerning that theme. It was a very intimidating scenario in my view, however , understanding your specialized avenue you resolved it took me to leap with delight. I’m just happier for this assistance and then have high hopes you comprehend what an amazing job you are putting in training the others by way of a blog. I am certain you haven’t met all of us.

Reply

At times like this it boils down to finding the information required, which as I’m sure you know can take some time. This post helped me figure out what I needed.

Reply

Really informative blog article.Thanks Again. Want more.

Reply

That is a great tip especially to those fresh to the blogosphere. Simple but very precise information Many thanks for sharing this one. A must read article!

Reply

Very nice write-up. I absolutely love this site. Thanks!

Reply

Here are a few of the web sites we advise for our visitors.

Reply

Sites of interest we have a link to.

Reply

Good day! I know this is somewhat off topic but I was wondering if you knew where I could locate a captcha plugin for my comment form? I’m using the same blog platform as yours and I’m having difficulty finding one? Thanks a lot!

Reply

Do you mind if I quote a couple of your posts as long as I provide credit and sources back to your webpage? My blog site is in the exact same niche as yours and my visitors would genuinely benefit from a lot of the information you present here. Please let me know if this ok with you. Cheers!

Reply

Hiya, I am really glad I’ve found this info. Nowadays bloggers publish only about gossip and net stuff and this is actually annoying. A good web site with interesting content, that’s what I need. Thank you for making this site, and I will be visiting again. Do you do newsletters by email?

Reply

That may be the finish of this article. Right here you will discover some web pages that we feel you?ll value, just click the links.

Reply

We came across a cool website that you could love. Take a look should you want.

Reply

Always a significant fan of linking to bloggers that I adore but don?t get a whole lot of link love from.

Reply

Some really howling work on behalf of the owner of this website , absolutely outstanding articles.

Reply

you are really a good webmaster. The website loading speed is incredible. It seems that you are doing any unique trick. In addition, The contents are masterpiece. you’ve done a excellent job on this topic!

Reply

We like to honor numerous other internet web-sites on the web, even when they aren?t linked to us, by linking to them. Underneath are some webpages worth checking out.

Reply

Please stop by the web sites we stick to, like this a single, because it represents our picks through the web.

Reply

Although web-sites we backlink to below are considerably not related to ours, we really feel they may be actually worth a go by way of, so possess a look.

Reply

The details mentioned within the report are a few of the best offered.

Reply

Here are several of the websites we advocate for our visitors.

Reply

Every the moment in a while we decide on blogs that we study. Listed beneath are the most recent web pages that we decide on.

Reply

I will right away seize your rss as I can not in finding your email subscription hyperlink or newsletter service. Do you have any? Kindly let me recognise so that I may subscribe. Thanks.

Reply

Although web sites we backlink to below are considerably not associated to ours, we really feel they are really worth a go by, so possess a look.

Reply

We like to honor several other world-wide-web websites on the net, even if they aren?t linked to us, by linking to them. Below are some webpages worth checking out.

Reply

Here are some hyperlinks to websites that we link to for the reason that we believe they are worth visiting.

Reply

Check beneath, are some totally unrelated internet sites to ours, nonetheless, they are most trustworthy sources that we use.

Reply

One of our guests lately encouraged the following website.

Reply

We like to honor many other world-wide-web internet sites on the web, even when they aren?t linked to us, by linking to them. Under are some webpages really worth checking out.

Reply

Sites of interest we’ve a link to.

Reply

Just beneath, are various absolutely not associated websites to ours, on the other hand, they may be certainly worth going over.

Reply

Every as soon as inside a though we pick out blogs that we read. Listed below are the latest websites that we choose.

Reply

That could be the end of this write-up. Right here you?ll find some web-sites that we think you?ll enjoy, just click the hyperlinks.

Reply

Please visit the web pages we comply with, like this 1, because it represents our picks through the web.

Reply

We prefer to honor lots of other net websites around the web, even if they aren?t linked to us, by linking to them. Beneath are some webpages really worth checking out.

Reply

Just beneath, are quite a few completely not related internet sites to ours, even so, they may be certainly worth going over.

Reply

Here are some hyperlinks to sites that we link to because we assume they’re really worth visiting.

Reply

Here are some of the websites we suggest for our visitors.

Reply

Although internet sites we backlink to beneath are considerably not related to ours, we really feel they may be in fact worth a go as a result of, so have a look.

Reply

Below you will discover the link to some sites that we assume it is best to visit.

Reply

The data talked about in the post are some of the top obtainable.

Reply

Every as soon as inside a when we select blogs that we study. Listed beneath are the latest websites that we select.

Reply

Here are some links to web pages that we link to since we think they may be worth visiting.

Reply

Here are some links to web sites that we link to mainly because we consider they’re worth visiting.

Reply

Just beneath, are quite a few entirely not connected internet sites to ours, on the other hand, they are certainly really worth going over.

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>