This project is archived and is in readonly mode.

#3658 ✓resolved
Jens

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

  • Matthew Bass

    Matthew Bass February 22nd, 2010 @ 03:01 AM

    +1, this this has bitten me as well

  • Darnell Brawner

    Darnell Brawner March 5th, 2010 @ 04:06 PM

    I am having the same issue using dirty attributes to create a change log.

  • Jeremy Kemper

    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

    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

    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

    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

    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"?

  • bingbing

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>

Referenced by

Pages