在 Postgres 中复制 Rails 时区 "magic"
Replicating Rails timezone "magic" in Postgres
有没有办法让 Postgres(我使用 Navicat,但将通过命令行工具进行演示)在时区和 UTC 方面的行为与 Rails 相同?
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
vs -08
),更令人困惑的是,它们 return 实际时间不同。
Postgres 示例 return 比 Rails 提前 16 小时获得结果!
在我的理解中,这不是 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,你的结果没有;你的默认时区似乎在美洲大陆的某个地方(8 小时在 UTC 之后)。您可以通过以下方式查看:
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"。
有没有办法让 Postgres(我使用 Navicat,但将通过命令行工具进行演示)在时区和 UTC 方面的行为与 Rails 相同?
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
vs -08
),更令人困惑的是,它们 return 实际时间不同。
Postgres 示例 return 比 Rails 提前 16 小时获得结果!
在我的理解中,这不是 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,你的结果没有;你的默认时区似乎在美洲大陆的某个地方(8 小时在 UTC 之后)。您可以通过以下方式查看:
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"。