在自定义日期/时间列上设置时区

时间:2016-02-21 04:36:16

标签: ruby-on-rails ruby postgresql

我使用Rails的常见用例(对我来说)是使用自定义查询,比如这个简化的

> User.select("NOW() as now").first.now
  User Load (0.9ms)  SELECT  NOW() as now FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
 => 2016-02-21 04:22:04 UTC

这里的问题是,时区与我在模型上使用预定义列的方式不同,例如created_at

> User.first.created_at
  User Load (5.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
 => Wed, 20 Mar 2013 02:13:27 CET +01:00

这是另一个。这是一个更复杂的例子,它只是再次获取created_at coumn,但是在子查询中。

user = User.select(%q{
  (
    SELECT created_at 
    FROM users u 
    WHERE u.id = users.id 
    LIMIT 1
  ) as custom_created_at, created_at
}).first

user.custom_created_at.strftime("%F %H:%M") # => "2013-03-20 01:13"
user.created_at.strftime("%F %H:%M") # => "2013-03-20 02:13"

我尝试过全局设置时区,就像这样

config.time_zone = "Stockholm"
config.default_timezone = :local

但它只适用于预定义列,例如created_at

请注意,我可以使用Time#in_time_zone手动设置时区对象的时区,如下所示

> User.select("NOW() as now").first.now.in_time_zone("Stockholm")
  User Load (1.5ms)  SELECT  NOW() as now FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
 => Sun, 21 Feb 2016 05:25:01 CET +01:00

但我不想手动对所有查询进行此操作。关于如何解决这个问题的任何想法?

这个特殊项目使用的是Ruby 2.2.2和Rails 5 beta 2,但我想说它适用于Rails 3之上的所有版本。

2 个答案:

答案 0 :(得分:1)

如何设置

 config.active_record.default_timezone = 'xxxxxx'

application.rb

答案 1 :(得分:1)

@Hassan的答案暂时正常,但正如@Harfangk在上面的评论中所提到的,这也改变了存储在数据库中的所有现有日期列。这在我的应用程序中引起了很多问题,其中一个是使用回形针上传的所有图片都停止工作(因为路径是使用neo4j start列计算的)。

所以我最后编写了自己的关注点,它暴露了一个API,让你定义应该手动转换的列。

有一个用例示例。

created_at

这是实施。它使用class User < ApplicationRecord include TimeZoneColumns timezone_columns :custom_created_at end user = User.select(%q{ ( SELECT created_at FROM users u WHERE u.id = users.id LIMIT 1 ) as custom_created_at, created_at }).first user.custom_created_at.strftime("%F %H:%M") # => "2013-03-20 01:13" OK user.created_at.strftime("%F %H:%M") # => "2013-03-20 01:13" OK 并在您的环境中设置Time#in_time_zone。我的测试支持逻辑。

config.time_zone