Using beginning_of_day
or end_of_day
on Date
or DateTime
objects in Rails 2.x applications will never respect time zones, which is horrible.\
This is fixed in Rails 3, though.
Even when using Date.current
or DateTime.current
you will get regular Time
or DateTime
objects:
>> Date.current.beginning_of_day.class
=> Time # not a ActiveSupport::TimeWithZone as expected
>> DateTime.current.beginning_of_day.class
=> DateTime # not a ActiveSupport::TimeWithZone as expected
This means that whenever you are using those values for database interaction, you'll end up scoping on the wrong records since the database representation of these dates is not converted to UTC:
>> Date.current.beginning_of_day.to_s(:db)
=> "2012-05-22 00:00:00"
>> DateTime.current.beginning_of_day.to_s(:db)
=> "2012-05-22 00:00:00"
You need to work around it yourself:
>> Date.current.beginning_of_day.in_time_zone(Time.zone).class
=> ActiveSupport::TimeWithZone # This is what you want.
>> Date.current.beginning_of_day.in_time_zone(Time.zone).to_s(:db)
=> "2012-05-21 22:00:00" # When on +0200, this is midnight's UTC.
>> DateTime.current.beginning_of_day.in_time_zone(Time.zone).class
=> ActiveSupport::TimeWithZone # This is what you want.
>> DateTime.current.beginning_of_day.in_time_zone(Time.zone).to_s(:db)
=> "2012-05-21 22:00:00" # When on +0200, this is midnight's UTC.
If you feel you have the balls for it, you could also monkey-patch beginning_of_day
and end_of_day
so it works correctly for Date
and DateTime
.
Posted by Arne Hartherz to makandra dev (2012-05-22 08:20)