Vita Rara: A Life Uncommon

Skipping UTC Conversion of Date/DateTime in ActiveRecord


Categories: | |

I'm in the process of porting an application from Java/Groovy to Ruby on Rails. All of our times are stored in the database in local time. So, I needed ActiveRecord to store a time without converting it to UTC, which 2.2 does by default. (I'm not sure when UTC became the standard though, could have been before 2.2.)

After some Googling and asking on IRC it was suggested I try:

config.active_record.default_timezone = :local

This sets the ActiveRecord::Base.default_timezone class attribute. Unfortunately that didn't seem to have the desired effect. Dates were still stored in UTC but when retrieved via accessors they were converted to local time. Not what I wanted.

So, at this point I dug into the code. (When in doubt with Rails just open the code up and read. You might learn a thing or two, and you'll understand your framework better.) I thought I might have to monkey-patch AR's date handling but thankfully that wasn't necessary.

In ActiveRecord::Base there is a private method instantiate_time_object which calls create_time_zone_conversion_attribute? to find out if conversion for that particular attribute is necessary. create_time_zone_conversion_attribute? consults an array called skip_time_zone_conversion_for_attributes. Any column that is in skip_time_zone_conversion_for_attributes will not be converted by AR when it stores the time in the database.

I added the following to my model and all is well:

skip_time_zone_conversion_for_attributes << :startTime

(Yes, that's a camel case attribute. It's a port from Java to Rails.)

Thankfully I deal with lots of dates, but few actual times. I don't know if there is a more global configurable solution. If you know of one please post it for others, this solution was good enough for me.

tested in 2.3.2, to do it

tested in 2.3.2, to do it globally:

 config.active_record.default_timezone = :local

and make sure you don't set config.time_zone

many many thanks for your support

Many many thanks for your support. It works dude.