Erik Trautman logo crest shield seal

Erik Trautman

“Everything you can imagine is real.”
-- Pablo Picasso

Ruby Explained: Dates and Times

This post will cover the basics of working with dates and times in Ruby

When you’re building a website, you’ll inevitably come into contact with dates and times. When was that submitted? Show only posts created after this time. How long has that user been registered?

All languages have conventions for how they keep track of dates and times and, of course, Ruby is no different… just a bit easier than the rest. In general, computers keep track of time in terms of seconds since a specified point in time. Someone decided a long time ago that Time shall begin at midnight on January 1st, 1970, and so that’s typically the "0th" second.

Ruby uses the Time class to let you work with dates and times, giving you some handy methods to find out about specific parts (like what day of the week it is) and to allow you to display them in a user-friendly fashion. You probably won’t need to dive too deeply into this stuff until you start working with Rails but you do need to understand the basics (as laid out below).

To Get Current Time you just create a new Time object with no parameters or use Time.now, which is the same thing:

> Time.new
=> 2013-07-10 17:04:10 -0700
> Time.now
=>2013-07-10 17:04:11 -0700

Time gives you some handy methods to ask it questions. Almost all of them are very intuitive, so the general rule is "if you think the method should exist, it probably does":

> my_time = Time.now
=> 2013-07-10 17:04:10 -0700
> my_time.year
=> 2013
> my_time.month
=> 7
> my_time.day
=> 10
> my_time.wday
=> 0                # the day of the week, starting Sunday
> my_time.hour
=> 17
> my_time.min
=> 4
> my_time.sec
=> 10

Time also takes inputs if you want to create a specific time, from year to time zone:

Time.new(year, month, day, hour, min, sec, time_zone_offset_from_utc)

> Time.new(2012,2,14)
=> 2012-02-14 00:00:00 -0800

You can add and subtract times just like they were numbers (because, remember, they basically are… just the number of seconds since 1970):

> vday = Time.new(2012,2,14)    # Valentine's Day!
=> 2012-02-14 00:00:00 -0800
> vday+3600                     # 1 hour's worth of seconds
=> 2012-02-14 01:00:00 -0800
> xmas = Time.new(2013,12,25)
=> 2013-12-25 00:00:00 -0700    # Xmas!
> ( xmas - Time.now )/60/60/24.to_i
=> 167                          # That's too long...

What if you want to display a date in a pretty way, like on your website or for your user’s benefit? There are a couple of baked in methods and then a "build-your-own-adventure" way to specify:

> nownow = Time.now
=> 2013-07-10 17:37:27 -0700
> nownow.ctime                  # a standard display type
=> "Wed Jul 10 17:38:10 2013"
> nownow.utc                    # Remove the time zone
=> 2013-07-11 00:38:10 UTC
> nownow.strftime("%Y-%m-%d %H:%M:%S")
=> "2013-07-11 00:38:10" 

Wait, what were all those %Y characters? They just tell the strftime method what components of the Time to output and how you’d like them formatted. There’s a long list of them back at the TutorialsPoint site. You don’t need to remember them since you can just google for them when you decide to output a string, but know that they give you the flexibility to output a date or time in pretty much any way you could imagine.

Extra Stuff: Time Zones and Local Time
What’s that trailing -0800 in 2012-02-14 00:00:00 -0800? It’s because that time was created on my local system, which is many hours "earlier" in the day from the Coordinated Universal Time (called UTC… no, it doesn’t match up but here’s why) which is used by computers around the world as the standard benchmark time (so two computers communicating about times will always be talking about the same exact one and not have to worry about time zones).

I prefer to think of UTC as "Universal Time Code" because reasons. UTC is the new GMT… Greenwich Mean Time. You’ll start thinking of things in terms of "how many hours away am I from England?" when you run into time zone bugs somewhere down the road.

Back to the point, the -0800 above says that we created a new time for midnight on Valentine’s Day but only from the perspective of someone on the West Coast of the USA… it was really 8am in Greenwich, England and according to every other computer in the world. You’ll forget this stuff until you need it and that’s fine.

Use localtime to display the Time object in whatever your local system time is (if it was created in UTC it will be different).


*The “Ruby Explained” posts are designed to be a sort of “In-Plain-English” version of key Ruby concepts which are usually covered in other introductory texts but rarely for free and often incompletely. When I’m learning a new thing, I usually want someone to explain it to me like I’m a five year old because that’s the best way to make sure nothing gets missed. This is my attempt to pass that same sentiment on to you. Let me know if there’s anything I can improve.*

If you’re just getting interested in this stuff, check out The Odin Project for a free curriculum to learn web development.