This project is archived and is in readonly mode.
Dirty datetime attributes lose time zone info
Reported by Jens | January 5th, 2010 @ 03:15 PM | in 2.3.6
When modifying a datetime attribute of an ActiveRecord object, its history is saved but without time zone information. Example:
>> q.start_at
=> Tue, 24 Nov 2009 11:21:08 CET +01:00
>> q.start_at_was
=> Tue, 24 Nov 2009 11:21:08 CET +01:00
>> q.start_at = Time.zone.now
=> Tue, 05 Jan 2010 16:09:52 CET +01:00
>> q.start_at
=> Tue, 05 Jan 2010 16:09:52 CET +01:00
>> q.start_at_was
=> Tue Nov 24 10:21:08 UTC 2009
I would expect q.start_at_was to return the old CET value, also after the change.
q is an instance of a normal ActiveRecord object, start_at is a datetime column (served from a PostgreSQL 8.3 server with all timezones turned off). Using Rails 2.3.4, Ruby 1.8.6, on Mac OS X.
Comments and changes to this ticket
-
Darnell Brawner March 5th, 2010 @ 04:06 PM
I am having the same issue using dirty attributes to create a change log.
-
Jeremy Kemper March 5th, 2010 @ 04:34 PM
- State changed from new to open
- Assigned user set to Jeremy Kemper
- Milestone set to 2.3.6
-
Kristopher Murata April 8th, 2010 @ 07:36 AM
This is happening because when storing the old attributes on @changed_attributes hash the datetime attributes were being transformed from ActiveSupport::TimeWithZone to just Time:
irb(main):007:0> p.created_at.class => ActiveSupport::TimeWithZone irb(main):009:0> p.created_at = Time.now => Thu Apr 08 00:59:46 -0400 2010 irb(main):011:0> p.created_at.class => ActiveSupport::TimeWithZone irb(main):012:0> p.created_at_was.class => Time
The funny part is that is that ActiveSupport::TimeWithZone objects are created on-the-fly by the module ActiveRecord::AttributeMethods::TimeZoneConversion which overwrite read/write methods for datetime/timestamp columns when ActiveRecord::Base.time_zone_aware_attributes = true, so when cloning (ActiveRecord::Base.clone_attribute_value) datetime attributes it was getting the object Time and not ActiveSupport::TimeWithZone.
My approach on this patch is storing on @changed_attributes the actual ActiveSupport::TimeWithZone object when ActiveRecord::Base.time_zone_aware_attributes = true and the attribute is not on skip_time_zone_conversion_for_attributes hash.
I don't know if it's the right way to attack this issue, it's just a try.. :)
-
Kristopher Murata April 8th, 2010 @ 08:41 AM
Ops, noticed that I broke one test by note keeping my time zone configurations inside my test scope. Attached another patch with tests written right.
-
Repository April 8th, 2010 @ 06:28 PM
- State changed from open to resolved
(from [36129f21b86db4bd69e932e586129e246c2a5ca8]) Dirty datetime attributes should be aware of time zone info [#3658 state:resolved]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
http://github.com/rails/rails/commit/36129f21b86db4bd69e932e586129e... -
StuFF mc July 17th, 2010 @ 09:50 AM
- Importance changed from to Medium
Turns out the problem is the same (2.3.8) when accessing .attributes (http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001863). Eg:
>> User.first.attributes["created_at"] => Sun Oct 04 22:36:44 UTC 2009 >> User.first.created_at => Mon, 05 Oct 2009 00:36:44 CEST 02:00 >> User.first.attributes_before_type_cast["created_at"] => "2009-10-04 22:36:44" >> User.first.created_at.class => ActiveSupport::TimeWithZone >> User.first.attributes["created_at"].class => Time >> User.first.attributes_before_type_cast["created_at"].class => String
How can I "keep" the timezone when accessing ".attributes"?
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Attachments
Referenced by
- 3658 Dirty datetime attributes lose time zone info (from [36129f21b86db4bd69e932e586129e246c2a5ca8]) Dirty d...