为什么Ruby续集和Postgres psql的时区信息有所不同?

时间:2012-08-01 22:32:50

标签: ruby postgresql timezone

以下是Postgres的查询结果:

$ psql ... -c 'select the_date from foo where foo_id in (998,999)'
     the_date      
------------------------
 2012-03-07 09:34:47.98
 2012-03-16 11:31:25.336

the_date是“没有时区的时间戳”。

这是一个Ruby程序:

#!/usr/bin/env ruby

require 'sequel'

@DB = Sequel.connect({...})
query = "select the_date from foo where foo_id in (998,999)"
@DB[query].each do |row|
  warn row
end

和一些输出:

{:the_date=>2012-03-07 09:34:47 -0600}
{:the_date=>2012-03-16 11:31:25 -0500}

-0500和-0600来自哪里?这是服务器和客户端机器(US / Central)的“Olson timezone”,但为什么Ruby添加它而psql没有?

我一直在阅读the docs,我很困惑。

服务器是Postgres 9.0.4,客户端是psql 9.1.4,续集是3.33.0。

2 个答案:

答案 0 :(得分:2)

该列的类型为'timestamp without timezone'。因此,当Postgres在此列中显示值时,它只显示没有时区的时间戳。但是,Sequel想要将Postgres时间戳转换为Ruby Time类的实例,并且Time类的实例必须指定时区 - 要么是本地时区的时间,要么是UTC的时间。因此续集必须选择一个。默认情况下,它会选择您当地的时区。

您可以在Sequel中配置数据库和应用程序时区。见http://sequel.rubyforge.org/rdoc/classes/Sequel/Timezones.html

例如,这是我使用的数据库的默认续集行为:

>   c['select * from actors'].each do |row|; puts row[:created_at]; end
Thu Jul 12 20:33:17 -0400 2012

此处假设时间戳位于我当地时区(EDT)。

但是,如果我这样做:

> Sequel.database_timezone = :utc
 => :utc 
> c['select * from actors'].each do |row|; puts row[:created_at]; end
Thu Jul 12 20:33:17 UTC 2012

然后假设时间戳为UTC。

答案 1 :(得分:0)

我与ruby和日期/时间/时间戳有一些奇怪的交易。看起来程序试图将结果转换为已知的数据类型并自动转换它,这就是为什么你在最后收到5digit时区代码。