Telling Time with Ruby

Walk through many of the immensely cool things you can do with Ruby's Time class.

provided by: 
Originally published at Internet.com


Ask any Ruby developer what led them to embrace the language, and most will praise its "beauty," comparing Ruby's syntax to a eloquent poem or piece of art. Admittedly, this sort of aggrandization used to elicit a sneer from yours truly, although at that point I'd never actually looked into the language to determine what all of the fuss was about. That is, until one day a single line of Ruby code caught my attention while surfing online: 7.days.ago

Made possible through the Active Support gem, when executed, this line of code will return the date and time occuring exactly seven days prior to its execution. Today being Valentine's day, executing this code now will return: Thu Feb 14 11:10:26 -0500 2008

Although I'm not yet prepared to place the language alongside the Picasso's and Chagall's hanging in the Met, since encountering this mere line of code I've been utterly hooked on the language. But, this example is just the tip of the iceberg when it comes to Ruby's intuitive date and time parsing and calculation capabilities. In this tutorial, I'll introduce you to some of the language's temporal features, helping you to turn what is traditionally a frustrating aspect of programming into something that's fun and productive.

An Exploration of Time

The best way to become familiar with Ruby's time features is to fire up the interactive Ruby shell (IRB) and start experimenting. To do so, open a terminal and execute irb. Start simple and determine the current date and time, done with the DateTime class' now method: irb>DateTime.now => Thu, 14 Feb 2008 13:19:21 -0500

You can take advantage of a number of methods to learn more about the current time and date: irb>DateTime.now.year => 2008 irb>DateTime.now.month => 2 irb>DateTime.now.day => 14 irb>DateTime.now.hour => 09 irb>DateTime.now.min =>32 irb>DateTime.now.sec =>59

You also can use the DateTime class to learn more about a given date's surroundings. For instance, what will the date be four years from now, and what was it four years ago? irb>DateTime.now.years_since(4) => Tue, 14 Feb 2012 13:37:42 -0500 irb>DateTime.now.years_since(4) => Sat, 14 Feb 2004 13:37:42 -0500

You also can use DateTime's methods to calculate the beginning of the current month and beginning of the current quarter: irb>DateTime.now.beginning_of_month.to_date => Fri, 01 Feb 2008 irb>DateTime.now.beginning_of_quarter.to_date => Tue, 01 Jan 2008

How about determining the current day of the week? You can use the strftime method to determine this and so much more. strftime works similarly to PHP's strftime() function, accepting a time, bject, and formatting it according to a set of directives. The list of directives is too long to list here, so refer to the previous link for a complete breakdown. Returning to the objective, use strftime to learn more about today's weekday: irb>DateTime.now.strftime("%A") => Thursday

Remember the somewhat user-unfriendly string returned by Time.now? What if you wanted to recreate the current date/time in a friendlier form? You can use several of strftime's directives to create whatever format you please: irb>DateTime.now.strftime("%b %d, %Y") => "Feb 14, 2008" irb>DateTime.now.strftime("Today is %A, %I:%M%p") => "Today is Thursday, 12:21PM" irb>DateTime.now.strftime("%Y-%m-%d") => "2008-02-14"

Calculating the Number of Days Between Two Dates

TThe previous examples are all interesting, but programmers don't always live in the here and now. Often, they're tasked with working with dates residing well into the future and the past. For instance, what if you wanted to calculate the distance between Memorial Day and the Fourth of July? irb>memorial = DateTime.new(2008,05,31) => Sat, 31 May 2008 00:00:00 +0000 irb>fourth = DateTime.new(2008,07,04) => Fri, 04 Jul 2008 00:00:00 +0000 irb>days = (fourth - memorial).to_i => 34

Never Be Late Again with Chronic

Ruby's built-in time and date parsing and calculation capabilities are great, but some really interesting work has been done by the community to really enhance the ability to perform some powerful temporal calculations. One of my favorite such projects is Chronic, a date/time parser that makes it possible to reference dates in a fascinating and natural fashion. Install Chronic through Ruby's gem system: %>gem install chronic

Once installed, fire up irb again and retrieve the Chronic library: require 'chronic'

Next, follow along with these examples to learn more about what Chronic has to offer: irb>Chronic.parse('yesterday') => Wed 13 Feb 2008 12:00:00 -0500 2008 irb>Chronic.parse('yesterday').to_date => Wed, 13 Feb 2008 irb>Chronic.parse('last monday').to_date => Mon, 11 Feb 2008 irb>Chronic.parse('next month').to_date => Sun, 16 Mar 2008 irb> Chronic.parse('3 months ago this friday at 3:45pm') => Thu Nov 15 15:45:00 -0500 2007

Chronic offers a second benefit that can be immensely useful if you're dealing with free-form dates. Suppose you wanted to analyze a data file that contains a bunch of dates, converting each to a Date object. These dates used inconsistent formatting, however, with some using dash separators, and others using slash separators. Chronic recognizes both: irb>Chronic.parse('07-04-2008').to_date => Fri, 04 Jul 2008 irb>Chronic.parse('07/04/2008').to_date => Fri, 04 Jul 2008

Suppose the inconsistency problem was worse than you expected, and you found an occasional date used a dash to separate the month and day, but a slash to separate the day and year? Chronic is capable of handling these too: irb>Chronic.parse('07-04/2008').to_date => Fri, Jul 04 2008

Rails and Dates

At the beginning of this tutorial, I referenced the great date-related features available through the Active Support gem. Active Support is an integral part of the Rails framework, meaning you can take advantage of all Active Support has to offer within your Rails applications. For instance, suppose you wanted to retrieve a list of users who have logged in within the last seven days: @users_recently_active = User.find(:all, :conditions => ["users.last_login < ?", 7.days.ago], :order => "last_login DESC")

User-Friendly Temporal Messages

Within Rails views, you can take advantage of other date/time-specific features introduced by another key gem used by Rails, named ActionView. For instance, suppose you wanted to provide users with a somewhat more friendly message indicating the last time a specific user logged in. The message might look something like this: This user was last visible 4 days ago

To implement this, all you need to do is use the ActionView helper time_ago_in_words: This user was last visible <%= time_ago_in_words(user.last_login)%> ago

Conclusion

I hope this brief tutorial regarding Ruby's amazing date and time manipulation capabilities gives you cause to consider exploring this powerful language! If you'd like to share a tip, email me at jasonATwjgilmore.com!

About the Author

W. Jason Gilmore is a freelance Web developer, consultant, and technical writer. He's the author of several books, including the best-selling Beginning PHP and MySQL 5: Novice to Professional, Second Edition (Apress, 2006. 913pp.).

Author: W. Jason Gilmore

Read article at Internet.com site
Regional Articles
- Telling Time with Ruby Alabama
- Telling Time with Ruby Alaska
- Telling Time with Ruby Arizona
- Telling Time with Ruby Arkansas
- Telling Time with Ruby California
- Telling Time with Ruby Colorado
- Telling Time with Ruby Connecticut
- Telling Time with Ruby DC
- Telling Time with Ruby Delaware
- Telling Time with Ruby Florida
- Telling Time with Ruby Georgia
- Telling Time with Ruby Hawaii
- Telling Time with Ruby Idaho
- Telling Time with Ruby Illinois
- Telling Time with Ruby Indiana
- Telling Time with Ruby Iowa
- Telling Time with Ruby Kansas
- Telling Time with Ruby Kentucky
- Telling Time with Ruby Louisiana
- Telling Time with Ruby Maine
- Telling Time with Ruby Maryland
- Telling Time with Ruby Massachusetts
- Telling Time with Ruby Michigan
- Telling Time with Ruby Minnesota
- Telling Time with Ruby Mississippi
- Telling Time with Ruby Missouri
- Telling Time with Ruby Montana
- Telling Time with Ruby Nebraska
- Telling Time with Ruby Nevada
- Telling Time with Ruby New Hampshire
- Telling Time with Ruby New Jersey
- Telling Time with Ruby New Mexico
- Telling Time with Ruby New York
- Telling Time with Ruby North Carolina
- Telling Time with Ruby North Dakota
- Telling Time with Ruby Ohio
- Telling Time with Ruby Oklahoma
- Telling Time with Ruby Oregon
- Telling Time with Ruby Pennsylvania
- Telling Time with Ruby Rhode Island
- Telling Time with Ruby South Carolina
- Telling Time with Ruby South Dakota
- Telling Time with Ruby Tennessee
- Telling Time with Ruby Texas
- Telling Time with Ruby Utah
- Telling Time with Ruby Vermont
- Telling Time with Ruby Virginia
- Telling Time with Ruby Washington
- Telling Time with Ruby West Virginia
- Telling Time with Ruby Wisconsin
- Telling Time with Ruby Wyoming
Rate Article
     
Articles Insider

Rss   Delicious   Digg   Add To My Yahoo   Add To My Google   Bookmark   Search Plugin

Topics:
Advertising Entertainment Home Services Retail & Consumer Services
Business Services Environmental Industrial Goods & Services Software
Career Family Insurance Technology
Cars Fashion Internet Telecommunications
Computer Hardware Financial Services Legal Transportation & Logistics
Construction Food & Beverage Pets Travel
Education Health Real Estate Wedding
Engineering Home Electronics