IdolHands.com :: Days in the Life of an Alpha Geek

Rails 2.1 added the ability to set a default time zone in your environment file, like this:
config.time_zone = 'Central Time (US & Canada)'
This defaults Time.zone to the zone specified, and also sets all date and time values written in your database to UTC (Coordinated Universal Time). Getters and setters for your ActiveRecord models adjust automatically, but there's a gotcha.
In script/console:
>> Time.now
=> Sun Mar 29 12:38:47 -0500 2009
>> c = Client.create(:name => "Date Test")
=> #<Client id: 6, address: nil, address_2: nil, , city: nil, country: nil, phone: nil, name: "Date Test", state: nil, url: nil, zip: nil, active: true, created_at: "2009-03-29 17:35:54", updated_at: "2009-03-29 17:35:54">
Notice that local time is 12:38, but the created_at in the database record is 5 hours in the future (UTC - Central Time = 5 hours). However, using an accessor, we get:
>> c.created_at
=> Sun, 29 Mar 2009 12:35:54 CDT -05:00
This is a Good Thing; the ActiveRecord getters and setters are respecting our time zone setting.
But here's the gotcha: if you manually create find conditions to locate records by a time or date, you can't just use Time.now as you might have in the past. For example:
>> Client.find(:last, :conditions => ['created_at < ?', Time.now - 5.minutes])
=> #<Client id: 4, address: "Rt 10 Green Hills", address_2: "P.O. Box 563", city: "Reading", country: "US", phone: "610-777-7777", name: "Some Other Client", state: "Pennsylvania", url: "http://www.foo.com", zip: "19603", active: true, created_at: "2008-10-28 15:00:19", updated_at: "2008-10-28 15:58:04">
This is not the record that we were expecting-- this one is months old!
To fix the find condition, you have to change Time.now to Time.zone.now:
>> Client.find(:last, :conditions => ['created_at < ?', Time.zone.now - 5.minutes])
=> #<Client id: 6, primary_agent_id: nil, primary_contact_id: nil, address: nil, address_2: nil, camp_directory_url: nil, city: nil, country: nil, local_site_meta_description: nil, local_site_meta_keywords: nil, phone: nil, name: "Date Test", state: nil, url: nil, zip: nil, active: true, created_at: "2009-03-29 17:35:54", updated_at: "2009-03-29 17:35:54">
This caused some amount of chaos for me last week, as one member of the team added time zone configuration and suddenly scheduled background tasks weren't running on schedule anymore. I strongly recommend searching your code base for Time.now and DateTime.now and modifying them accordingly; remember, anything that's using accessors is fine as is, but other calls may cause unexpected results.
Comments
Brad Gessler
04/12/2009
Damian Nicholson
05/18/2009
Jason
04/30/2010