简体   繁体   English

为什么 Ruby sequel 和 Postgres psql 的时区信息不同?

[英]Why does timezone info from Ruby sequel and Postgres psql differ?

Here is a query result from Postgres:这是来自 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 is "timestamp without time zone". the_date 是“没有时区的时间戳”。

Here is a Ruby program:这是一个 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

and some output:和一些 output:

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

Where does the -0500 and -0600 come from? -0500 和 -0600 来自哪里? That is the " Olson timezone " of the server and the client machines (US/Central), but why does Ruby add it and psql does not?那是服务器和客户端机器(美国/中部)的“奥尔森时区”,但为什么 Ruby 添加它而 psql 不添加?

I've been reading the docs , and I'm thoroughly confused.我一直在阅读文档,我很困惑。

The server is Postgres 9.0.4, the client is psql 9.1.4, sequel is 3.33.0.服务器是Postgres 9.0.4,客户端是psql 9.1.4,续集是3.33.0。

The column is of type 'timestamp without timezone'.该列的类型为“没有时区的时间戳”。 Thus when Postgres displays a value in this column it just displays the timestamp with no timezone.因此,当 Postgres 在此列中显示一个值时,它只显示没有时区的时间戳。 However, Sequel wants to convert a Postgres timestamp to an instance of the Ruby Time class, and an instance of the Time class must have a timezone specified - either it's a time in the local timezone or it's a time in UTC.但是,Sequel 想要将 Postgres 时间戳转换为 Ruby 时间 class 的实例,并且时间 class 的实例必须指定时区 - 要么是本地时区的时间,要么是 UTC 时间。 Thus Sequel must choose one.因此Sequel必须选择一个。 By default, it's choosing your local timezone.默认情况下,它选择您当地的时区。

You may configure the database and application timezone in Sequel.您可以在 Sequel 中配置数据库和应用程序时区。 See https://www.rubydoc.info/gems/sequel/4.36.0/Sequel/Timezones参见https://www.rubydoc.info/gems/sequel/4.36.0/Sequel/Timezones

For example, here's the default Sequel behavior with a database I had handy:例如,这是我手边的数据库的默认 Sequel 行为:

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

Here the timestamp is assumed to be in my local timezone (EDT).这里的时间戳假定在我的本地时区 (EDT) 中。

However, if I do this:但是,如果我这样做:

> 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

Then the timestamp is assumed to be in UTC.然后假定时间戳为 UTC。

I've had some strange dealings with ruby and dates/times/timestamps.我对 ruby 和日期/时间/时间戳进行了一些奇怪的处理。 It looks like the program is trying to convert the result into a known datatype and automatically casting it, which is why you receive the 5digit timezone code at the end.看起来该程序正在尝试将结果转换为已知数据类型并自动转换它,这就是为什么您在最后收到 5 位时区代码的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM