[英]How to set in Rails a default timezone for query or set offset for datetime value when migrating record from MySql to Postgres
I created a ruby class in my models folder to connect to a legacy MySQL database that by default uses Pacific/PT for datetime
columns. 我在我的models文件夹中创建了一个ruby类,以连接到默认情况下将Pacific / PT用于
datetime
列的旧版MySQL数据库。
However, rails is treating datetime
values from legacy database records as UTC as opposed PT/Pacific . 但是,rails将旧数据库记录中的
datetime
值视为UTC而不是PT / Pacific 。 Inserting this value into Postgres would be incorrect since Postgres timestamp (for rails) is timestamp without time zone
(therefore, value needs to be UTC). 将此值插入Postgres是不正确的,因为Postgres时间戳(用于rails)是
timestamp without time zone
(因此,值必须为UTC)。
How can I either 1) set my default_timezone
connection to be Pacific or 2) create some type of offset that will correctly convert the value to UTC? 我该如何1)将我的
default_timezone
连接设置为Pacific或2)创建某种类型的偏移量,以将值正确转换为UTC? For the later, how would an offset incorporate daylight savings time nuances? 对于后一种情况,偏移量将如何整合夏时制的细微差别?
Here's how I've confirmed the issue: 这是我确认问题的方法:
[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
First, find a time zone name that actually exists in your Postgres DB cluster: 首先,找到Postgres数据库集群中实际存在的时区名称:
SELECT *
FROM pg_timezone_names
WHERE name ~~* '%Pacif%'
OR abbrev = 'PT';
Then set this time zone in your session: 然后在会话中设置此时区:
SET timezone = 'US/Pacific';
Which means values from timestamp [without time zone]
columns are interpreted as being in this time zone, and timestamp [with time zone]
is offset from / to UTC accordingly on input / output. 这意味着来自
timestamp [without time zone]
列的值被解释为处于该时区,并且timestamp [with time zone]
于输入/输出的UTC偏移量。
There are many ways to set a config parameter in Postgres. 在Postgres中有很多方法可以设置配置参数。 Compare:
相比:
More information: 更多信息:
I solved this after a few days toiling with this issue. 经过几天的努力,我解决了这个问题。 It's somewhat of a subtle hack.
这有点微妙。
default_timezone
in rails can be either :local
or :utc
. rails中的
default_timezone
可以是:local
或:utc
。 So, since rails misinterpreted my Pacific-based Mysql records as 'utc' or -7 hours behind UTC, I had to change it back to UTC (really back to 'Pacific' since it was originally misinterpreted) and convert the value to a string. 因此,由于rails将我基于太平洋的Mysql记录误解为“ utc”或比UTC落后-7小时,因此我不得不将其改回UTC(由于最初被误解,所以实际上又改回了“ Pacific”)并将值转换为字符串。 ActiveRecord would then treat convert the string to Pacific (since in application.rb I have
config.time_zone = 'Pacific Time (US & Canada)'
) and then save it to Postgres in correct UTC format! 然后,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"
In my hash that would capture the legacy mysql values, I would have the below for created_at
and updated_at
: 在捕获旧版mysql值的哈希中,我将使用
created_at
和updated_at
的以下内容:
{
...
created_at: @legacy.ClientRecordAddDate.utc.to_s,
updated_at: @legacy.ClientRecordUpdateDate.utc.to_s
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.