views:

354

answers:

3

I'm implementing the Timezone support in Rails 2.1+, and I've run into an apparent bug in the way the data is pulled from the db. Let me try to set it up.

The "deals" model contains an "offer_date" datetime field. Let's say I have two records with these offer_dates:

Deal 1: 2009-12-29 23:59:59 -0500
Deal 2: 2009-12-28 23:59:59 -0500

This is correct: dates should mark the last second of its given day.

Now, when it comes time to find the deal for today, I have the following AR query:

@deal = Deal.first(:conditions=>['offer_date > ?', Time.now.beginning_of_day], :order=>"offer_date ASC")

In this case, although it's the 29th today, it returns the record ostensibly for the 28th. Why? Here's what happens in the console:

>> @deal = Deal.first(:conditions=>['offer_date > ?', Time.now.beginning_of_day], :order=>"offer_date ASC")
=> #<Deal id: 2, <blah blah blah...>, offer_date: "2009-12-29 04:59:00">

It's shifting the time forward by 5 hours, putting yesterday's day into the next. But when I do this:

>> @deal.offer_date
=> Mon, 28 Dec 2009 23:59:00 EST -05:00

I get the right time. What the heck??? Suffice to say, I need that date to work properly, but I can't figure out where my issue is. Any assistance you can provide would be greatly appreciated!

A: 

Instead of using Time.now, try using Time.zone.now

Of course you have to set this and everything. This tutorial seems helpful.

marcgg
+1  A: 

See my prior rsponse on Time vs Time.zone for AR date queries.

klochner
Ahhh, thanks again for your help! I'll get this eventually... :-)
Aaron Vegh
A: 

the Time class doesn't care about the time zone in the implementation of #to_s, therefore you have to use

Time.zone.now # or any other TimeWithZone object

in your finders/named_scopes/find calls. Or you could read through http://marklunds.com/articles/one/402 and then put

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module Quoting
      # Convert dates and times to UTC so that the following two will be equivalent:
      # Event.all(:conditions => ["start_time > ?", Time.zone.now])
      # Event.all(:conditions => ["start_time > ?", Time.now])
      def quoted_date(value)
        value.respond_to?(:utc) ? value.utc.to_s(:db) : value.to_s(:db)
      end
    end
  end
end

into your environment.rb or into an initializer.

severin