2012-08-01 28 views
1

下面是Postgres的查詢結果:爲什麼來自Ruby續集和Postgres psql的時區信息有所不同?

$ 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。

+0

您可能會發現在這[密切相關的問題](http://stackoverflow.com/q/9571392/939860)信息有用。 – 2012-08-01 23:24:59

回答

2

該列的類型爲'timestamp without timezone'。因此,當Postgres在此列中顯示一個值時,它只顯示沒有時區的時間戳。但是,Sequel希望將Postgres時間戳轉換爲Ruby Time類的實例,並且Time類的實例必須指定時區 - 要麼是本地時區的時間,要麼是UTC的時間。因此Sequel必須選擇一個。默認情況下,它選擇您的本地時區。

您可以在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。

+0

很好的答案,謝謝。因此Sequel的「本地時間戳」行爲足夠複雜,可以根據時間戳本身(因此-0500和-0600)考慮夏令時? – dfrankow 2012-08-02 04:01:37

+1

是的 - 雖然這種複雜性實際上來自Ruby的Time類。例如,對於我在東部地區,Time.parse('2012-03-07 09:34:47')。to_s給出「Wed Mar 07 09:34:47 -0500 2012」,而Time.parse(' 'to_s給「2012年3月16日星期五11:31:25 -0400」。 – 2012-08-02 04:07:27

0

我有一些奇怪的交易與紅寶石和日期/時間/時間戳。它看起來像程序試圖將結果轉換爲已知的數據類型並自動將其轉換,這就是爲什麼您在最後收到5位數時區代碼的原因。

相關問題