Postgres 或 Ruby 是否将时区添加到我的“没有时区的时间戳”列中?

发布于 2024-11-04 17:33:01 字数 443 浏览 3 评论 0原文

如果我使用 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”。

问题:时区添加到整个堆栈的哪个位置?尽管我意识到很大程度上取决于我的堆栈的具体情况,但这确实有助于理解应该发生什么,以便我可以排除问题。例如,对于没有时区的时间戳列,我是否应该期望 JDBC 驱动程序提供没有时区信息的“原始”值?

If I query my database with SELECT current_setting('TIMEZONE') I get 'UTC' (as expected).

Using PgAdmin, I run the following query:

SELECT foo FROM bar

PgAdmin shows "2011-03-12 08:00:00". However, when I read the value from Ruby (using DataMapper which uses the 'org.postgresql.Driver' JDBC driver as far as I know), it shows "2011-03-12 08:00:00 -0700".

Question: Where in the whole stack is the timezone getting added? Although I realize a lot depends on the specifics of my stack, it would really help to understand what should happen so that I can rule things out. For example, for a timestamp without time zone column, should I expect that JDBC driver gives a 'raw' value with no timezone information?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

巡山小妖精 2024-11-11 17:33:01

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 查询并查看返回的字符串来检查这一点。

Something in Ruby is making the timezone adjustment:

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)

You can check this by doing a raw SQL query of a timestamp from within Ruby and seeing what string you get back.

述情 2024-11-11 17:33:01

当读取没有时区的时间戳时,JDBC 驱动程序会大胆/合理地假设该时间戳是用 JVM 时区表示的。

The JDBC driver when reading a timestamp without timezone makes bold/reasonable assumption that this timestamp is expressed in the JVM timezone.

所有深爱都是秘密 2024-11-11 17:33:01

如果您不想添加时区,请使用类型“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 观察值,我得出的结论是

  • 没有时区的时间戳永远不会被转换。无论您位于哪个时区,您都会读取相同的秒/小时/分钟/日/月/年所插入的内容。

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

If you do not want timezone to be added, use type 'timestamp without timezone'.
That way, reader will always read same second/hour/minute/day/month/year as you inserted.

I used following procedure to reproduce that

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;

Observing values from select, I come to conclusion that

  • timestamp without timezone is never converted. You read same second/hour/minute/day/month/year what you inserted, no matter what timezone you are in.

    • timestamp with timezone converts values you read to your timezone. they represent same instant (point in time) but hour (and sometimes days, sometimes even minutes) values will be diffrent.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文