Don't assign time values to date attributes
Do not pass times to date attributes. Always convert times to dates when your application uses time zones.
Time attribute on a Rails record is converted to UTC using
to_s(:db) to be stored, and converted back into the correct time zone when the record is loaded from the database. So when you are not on UTC, time objects will be converted as follows.
>> Time.current => Fri, 15 Mar 2013 11:56:03 CET +01:00 >> Time.current.to_s(:db) => "2013-03-15 10:56:03" # This is now UTC
That will blow up in your face when you send times to attributes that expect dates, just because those times will also be converted using
to_s(:db) and sent to MySQL. The database itself does not care about the (longer) value and just stores the date part.
This means that whenever you pass a time that is within X hours away from midnight (where X is your +UTC time difference) you will store incorrect dates:
# Just like above, but we're close to midnight: >> Time.current => Sat, 01 Jan 2050 00:15:00 CET +01:00 >> Time.current.to_s(:db) => "2049-12-31 23:15:00" # This is the correct representation of our time. # Now let's create a record: >> SomeRecord.create! :my_date => Time.current >> SomeRecord.last.my_date => Fri, 31 Dec 2049 # Boom.
Note how the date should be 01/01/2050 but is not. This is because of the UTC timestamp string being cut off by the database. After all, it wants to store a date, not a time.
When dealing with dates, remember to always pass dates. So use
Date.current, or if you want to say something like
3.days.from_now you must make sure to convert it via