rails 2 didn't respect timezone doing db query
So suppose we're storing UTC time in database,
while Time.now returns a local time (i.e. with local timezone).
This would be wrong:
User.first(:conditions => ['created_at < ?', Time.now])
Timezone information would be dropped when the query is
converted to SQL. Instead we shall call Time#utc before
passing it to ActiveRecord:
User.first(:conditions => ['created_at < ?', Time.now.utc])
But actually ActiveRecord is respecting ActiveSupport::TimeWithZone,
that is, if we're passing an instance of it, timezone information won't
be dropped:
User.first(:conditions => ['created_at < ?', Time.now.in_time_zone(8)])
The effect is exactly the same as the one calling Time.now.utc.
I don't think this is a good design. It's more like a bug IMO.
As pointed out at:
Rails Timezone Gotcha: ActiveRecord::Base.find does not convert Time objects to UTC
It's marked as "invalid" in Rails' issue tracker. I totally have no idea why.
ActiveRecord timezone issues
Here's a monkey patch modified from Peter Marklund.
# http://marklunds.com/articles/one/402
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.dup.utc.to_s(:db) : value.to_s(:db)
end
end
end
endI have no idea if Rails 3 fixed this.


0 retries:
Post a Comment
Note: Only a member of this blog may post a comment.