ActiveRecord Rails将created_at时间戳转换为查询所在的时区

时间:2014-07-28 11:30:16

标签: ruby-on-rails-3 datetime activerecord timezone timestamp

场合

我正在使用 UTC 作为应用程序时区的Rails应用程序,因此来自任何区域的任何用户的数据都将以UTC格式保存在数据库中。

让我们假设其中一位来自中部时间(美国和加拿大)的用户(与UTC相差5小时)在我的网站上注册 2014年7月28日下午6:45 。因此,数据库中用户的created_at将为 Mon,28 Jul 2014 23:45:00 UTC +00:00 。现在,同一个用户在 晚上7:30 的同一天在Photo模型中上传了一张照片。因此,用户的照片记录中created_at的值将为 星期二,2014年7月29日00:30:30 UTC +00:00

因此,以UTC为单位存储值会在用户created_at与为用户存储的照片之间产生 1天的差异,尽管用户在网站上注册的同一天实际上传了照片。 / p>

要求

我想查找用户在用户创建的同一天创建的所有上传的照片。所以我实现了查询 -

预期结果 => 1

u = User.first
u.created_at
=> Mon, 28 Jul 2014 23:45:00 UTC +00:00

u.photos.where('Date(created_at) = ?', u.created_at).count
=> 0 {Failed - Because the db compares the time in UTC}

经过大量的搜索和研究后,我开始了解如何将Time.zone设置为用户时区。

u = User.first
Time.zone = u.time_zone
=> Central Time (US & Canada)

u = User.first
u.created_at
=> Mon, 28 Jul 2014 18:45:49 CDT -05:00 {Correct Time as per my requirements}

Photo.where('user_id = ? and Date(created_at) = ?', u.id, u.created_at).count
=> 0 {Failed}

但是当我试图找到用户上传的created_at照片记录时,它会返回正确的时间戳 -

u.photos.first.created_at
=> Sun, 28 Jul 2014 19:30:00 CDT -05:00

因此,设置Time.zone只能使Ruby在指定的时区内返回时间,但Rails Active Record会继续比较UTC的时间。

任何人都可以建议通过将时间戳从utc更改为用户time_zone来使用Active Record查询。

1 个答案:

答案 0 :(得分:0)

我知道这是一篇过时的帖子,但是如果其他人阅读了该帖子,我发现使用local_time gem可以帮助您,它可以将保存的日期显示在用户时区:https://github.com/basecamp/local_time

否则,如果您绝对必须更改数据库中的时区,那么我认为本教程可能就是您所需要的:https://gorails.com/episodes/auto-detect-user-time-zones-in-rails