如果我用SELECT current_setting('TIMEZONE')
查询我的数据库,我得到'UTC'(如预期的)。
使用PgAdmin,我运行以下查询:
SELECT foo FROM bar
PgAdmin显示"2011-03-12 08:00:00"。然而,当我从Ruby中读取值(使用DataMapper 使用'org.postgresql。据我所知,JDBC驱动程序)显示"2011-03-12 08:00:00 -0700"。
问题:在整个堆栈中添加时区的位置?虽然我意识到这在很大程度上取决于我的堆栈的具体情况,但它确实有助于理解应该发生什么,以便我可以排除某些情况。例如,对于timestamp without time zone
列,我是否应该期望JDBC驱动程序给出一个没有时区信息的"原始"值?
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查询并查看返回的字符串来检查这一点。
JDBC驱动程序在读取不带时区的时间戳时,会大胆/合理地假设该时间戳是用JVM时区表示的。
如果不希望添加时区,请使用type '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的值,我得出结论
- 没有时区的
时间戳永远不会被转换。无论您在哪个时区,您都会读取插入的相同秒/小时/分钟/日/月/年。
- timestamp with timezone将您读取的值转换为您的时区。它们表示相同的瞬间(时间点),但小时(有时是天,有时甚至是分钟)的值将不同。