The pitfall
Rails Active Support provides some helpful methods for calculating times and dates, like
Duration#ago
Show archive.org snapshot
or
Duration#from_now
Show archive.org snapshot
. But beware when using those, because they wont give you Date
s or Time
s but
ActiveSupport::TimeWithZone
Show archive.org snapshot
instances. As the class name hints, you now have to be aware of timezones, even though you may have decided to make your application timezone unaware.
Moreover, you have to be aware that ActiveSupport::TimeWithZone
does not use Rails.application.config.active_record.default_timezone
, which you need to define, even if you only use your local timezone, but Rails.application.config.time_zone
, which has UTC
as default value.
The mitigation
Best case, you have already defined Rails.application.config.time_zone
, as we recommend anyway. In this case you don't have to mind the pitfall.
In case your application is already running, and you haven't set a Rails.application.config.time_zone
so far, you can always avoid using those methods. However, if your mind is set on using them or you don't want to worry about which methods you should use or not, setting Rails.application.config.time_zone
is the only way to go. Before you do so, please compare timestamps for your ActiveRecord models and their representation in your database and make sure they are the same before you set a Rails.application.config.time_zone
.
Example
User.find(123).created_at
# => 2023-04-19 13:24:42.90857 +0200
User.connection.select_values("SELECT CAST(updated_at as text) FROM users WHERE id = 123")
# => ["2023-04-19 13:24:42.90857"]
If those values are not the same, you will corrupt your data by configuring a time zone.