在Postgres中复制Rails时区“魔术”

时间:2018-11-07 18:15:15

标签: ruby-on-rails ruby postgresql navicat

有没有办法让Postgres(我使用Navicat,但将通过命令行工具进行演示)的行为与Rails在时区和UTC方面的行为相同?

Rails似乎起到了某种神奇作用,使Postgres以UTC方式表现;而通过命令行(或Navicat)使用的是我的系统时区。这令人困惑,因为结果会因我是在Ruby / Rails中还是在控制台中执行查询而异。

我仍然在Postgres中的时区挣扎,但是让Rails和控制台表现出不同的行为令人发疯。我可以补救吗?

这里是一个示例(不同的输出值):

-- in postgress:
# select ('2018-11-06' at time zone 'utc')::timestamptz;
        timezone
------------------------
 2018-11-06 08:00:00-08
(1 row)

-- in rails console
> ApplicationRecord.execute("select ('2018-11-06' at time zone 'utc')::timestamptz").first
   (0.5ms)  select ('2018-11-06' at time zone 'utc')::timestamptz
=> #<OpenStruct timezone="2018-11-06 00:00:00+00">

它们的格式都不同(-00-08),更令人困惑的是,它们返回的实际时间不同。

Postgres示例比Rails提前16小时返回结果!

enter image description here

1 个答案:

答案 0 :(得分:2)

据我了解,这不是Rails的魔力,但Rails只是使用UTC作为默认值。这就是为什么Rails可以并且确实使用timezone而不是timezonetz或使用created_at的默认数据库类型等的原因。

如果愿意,您可以按以下方式修改Rails的默认时区(请参见official reference):

# application.rb:
class Application < Rails::Application
  config.time_zone = 'Eastern Time (US & Canada)'
end

对于PostgreSQL,您的结果不是不是似乎您的默认时区在美洲大陆某个地方(比UTC晚8个小时)。您可以按以下方式检查它:

postgres=> SET TIME ZONE 'America/New_York';
postgres=> select ('2018-11-06' at time zone 'UTC')::timestamptz;
        timezone        
------------------------
 2018-11-06 05:00:00-05
(1 row)

我不知道Navicat的作用。但也许请检查您的postgresql.conf。您可以根据需要将timezone重置为UTC(然后重新启动postgreSQL服务器)。 有关更多详细信息,请参见this answer to "postgres default timezone"