Posted over 5 years ago. Visible to the public. Repeats.

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.

Background

A time-zoned 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.

Copy
>> 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

Problem

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:

Copy
# 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 3.days.from_now.to_date.

Once an application no longer requires constant development, it needs periodic maintenance for stable and secure operation. makandra offers monthly maintenance contracts that let you focus on your business while we make sure the lights stay on.

Owner of this card:

Avatar
Arne Hartherz
Last edit:
9 months ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more