ruby-on-rails - 在 Postgres 中复制 Rails 时区 "magic"

标签 ruby-on-rails ruby postgresql navicat

有什么方法可以让 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),更令人困惑的是,它们返回的实际时间不同。

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

enter image description here

最佳答案

在我看来,这并不是 Rails 的魔法,而是 Rails 只是默认使用 UTC。这就是为什么 Rails 可以并且确实使用 timezone 而不是 timezonetzcreated_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"了解更多详情。

关于ruby-on-rails - 在 Postgres 中复制 Rails 时区 "magic",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53195407/

相关文章:

python - 如何从 Ruby 提交 Celery 任务

java - Spring Data JPA JpaRepository.save() 不返回默认值

mysql - 使用查询添加行值

ruby-on-rails - 在 EC2 上使用 bitnami 进行 Assets 预编译

css - Flash 消息打乱了 flexbox 布局

ruby-on-rails - Ruby on Rails 应用程序的 Heroku 错误日志

ruby-on-rails - Solidus 运费计算器错误

ruby - 在不同的上下文中使用方法,instance_eval 添加不需要的参数

mysql - 获取一张 table 售出的门票总数。 rails

postgresql - 从 SQL 获取 transactionid(xid)