Postgres或Ruby是否将时区添加到我的`timestamp without time zone`列?

时间:2011-05-03 18:46:20

标签: ruby postgresql jdbc timezone timestamp

如果我用SELECT current_setting('TIMEZONE')查询我的数据库,我会得到'UTC'(正如预期的那样)。

使用PgAdmin,我运行以下查询:

SELECT foo FROM bar

PgAdmin显示“2011-03-12 08:00:00”。但是,当我从Ruby读取值时(使用DataMapper ,据我所知使用'org.postgresql.Driver'的JDBC驱动程序),它显示“2011-03-12 08:00: 00 -0700“。

问题:整个堆栈中的时区是否添加了时区?虽然我意识到很多东西取决于我的堆栈的具体情况,但它真的有助于理解应该发生什么,以便我可以排除规则。例如,对于timestamp without time zone列,我是否应该期望JDBC驱动程序提供没有时区信息的“原始”值?

3 个答案:

答案 0 :(得分:2)

Ruby中的某些东西正在进行时区调整:

psql=> select current_setting('timezone');
 current_setting
-----------------
 Canada/Pacific
(1 row)

psql=> select min(created_at) from people;
            min
----------------------------
 2010-07-09 13:58:51.320659
(1 row)

psql=> set timezone = 'utc';
psql=> select current_setting('timezone');
 current_setting
-----------------
 UTC
(1 row)

psql=> select min(created_at) from people;
            min
----------------------------
 2010-07-09 13:58:51.320659
(1 row)

你可以通过在Ruby中对时间戳进行原始SQL查询并查看你得到的字符串来检查这一点。

答案 1 :(得分:1)

在没有时区的情况下读取时间戳时的JDBC驱动程序大胆/合理地假设此时间戳在JVM时区中表示。

答案 2 :(得分:0)

如果您不想添加时区,请使用类型' timestamp without timezone'。 这样,读者将始终读取与插入时相同的秒/小时/分钟/日/月/年。

我使用以下程序重现

create table t (
without_tz timestamp  without time zone ,
with_tz timestamp  with time zone 
)
SET SESSION TIME ZONE default;
insert into t VALUES ( now(), now() )
select * from t;
SET SESSION TIME ZONE PST8PDT;
insert into t VALUES ( now(), now() )
select * from t;
SET SESSION TIME ZONE PST6PDT;
insert into t VALUES ( now(), now() )
select * from t;

从select中观察值,我得出结论

  • 永不转换没有时区的时间戳。无论你在哪个时区,你都会读到相同的秒/小时/分钟/日/月/年。

    • 带时区的时间戳会将您读取的值转换为您的时区。它们代表相同的瞬间(时间点),但小时(有时甚至是几天,有时甚至是几分钟)的价值将是不同的。