我在models文件夹中创建了一个ruby类,用于连接到遗留MySQL数据库,默认情况下使用 Pacific / PT 作为datetime
列。
但是,rails将旧版数据库记录中的datetime
值视为 UTC ,而不是 PT / Pacific 。将此值插入Postgres将是不正确的,因为Postgres时间戳(对于rails)是timestamp without time zone
(因此,值必须是UTC)。
我怎样才能1)将default_timezone
连接设置为太平洋或2)创建某种类型的偏移,以便将值正确转换为UTC?对于后者,偏移如何包含夏令时的细微差别?
以下是我如何确认此问题:
[6] pry(LegacyClient)> @legacy.ClientRecordAddDate.to_yaml
=> "--- 2010-04-11 14:23:01.000000000 Z\n...\n"
[7] pry(LegacyClient)> @legacy.ClientRecordAddDate
=> Sun, 11 Apr 2010 07:23:01 PDT -07:00
[8] pry(LegacyClient)> self.default_timezone
=> :utc
答案 0 :(得分:0)
首先,找到Postgres数据库群集中实际存在的时区名称:
SELECT *
FROM pg_timezone_names
WHERE name ~~* '%Pacif%'
OR abbrev = 'PT';
然后在会话中设置此时区:
SET timezone = 'US/Pacific';
这意味着来自timestamp [without time zone]
列的值被解释为处于此时区,并且timestamp [with time zone]
在输入/输出上相应地从/向UTC偏移。
在Postgres中设置配置参数的方法有很多种。比较:
更多信息:
答案 1 :(得分:0)
我用这个问题辛苦劳作了几天后解决了这个问题。这有点微妙的黑客攻击。 rails中的default_timezone
可以是:local
或:utc
。因此,由于rails错误地将我的基于太平洋的Mysql记录误解为“utc”或比UTC低7个小时,我不得不将其更改回UTC(因为它最初被误解为“太平洋”)并将值转换为字符串。然后,ActiveRecord会将字符串转换为Pacific(因为在application.rb中我有config.time_zone = 'Pacific Time (US & Canada)'
),然后以正确的UTC格式将其保存到Postgres!
[2] pry(LegacyClient)> @legacy.ClientRecordAddDate.utc.to_s
=> "2010-04-11 14:23:01"
在我的哈希中捕获遗留的mysql值,我会在created_at
和updated_at
下面有以下内容:
{
...
created_at: @legacy.ClientRecordAddDate.utc.to_s,
updated_at: @legacy.ClientRecordUpdateDate.utc.to_s
}