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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ActiveRecord Rails将created_at时间戳转换为查询所在的时区相关的知识,希望对你有一定的参考价值。

情况:

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

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

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

需求:

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

预期结果=> 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查询。

答案

我知道这是一个旧帖子,但如果其他人阅读这篇文章,我发现帮助使用local_time gem,它将保存的日期呈现给用户时区:https://github.com/basecamp/local_time

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

以上是关于ActiveRecord Rails将created_at时间戳转换为查询所在的时区的主要内容,如果未能解决你的问题,请参考以下文章

Rails ActiveRecord:PG::Error:错误:列引用“created_at”不明确

Postgres 13.2 on rails 5.2.4.1: ActiveRecord::NoDatabaseError: FATAL: database * does not exist on r

rails/mysql - 我如何消除 ActiveRecord::StatementInvalid 错误?

有没有办法在后续 Rails 3 ActiveRecord 迁移中删除 id 列?

ActiveRecord::Migration 的 create_join_table 的行为是啥?

Rails ActiveRecord Timestamp in Epoch 而不是 DateTime 格式