带时区的 PostgreSQL 时间戳在读取时应用偏移量

PostgreSQL timestamp with timezone apply offset when reading

首先,我知道有很多关于此的话题,我可以使用那里的解决方案,f.e。编写一个 python 函数,将日期时间对象转换为我需要的时区,并将其作为过滤器添加到 jinja2。

但是我想跳过这一步。

通常 PostgreSQL 在 UTC.

中保存日期时间对象

我所做的是:我将 postgreSQL 用于保存日期时间对象的默认时区更改为:Europe/Berlin

ALTER DATABASE postgres SET timezone TO 'Europe/Berlin';

这有效,SHOW timezone; 告诉我它 Europe/Berlin

但是 Postgres 所做的,它仍然将日期时间保存为 UTC,但是 Europe/Berlin 有 +1 偏移量,这实际上不是问题。

我假设在读取日期时间对象时,Postgres 会应用偏移量和 return Europe/Berlin 时间,但事实并非如此。它仍然是 returnUTC 时间,那么更改时区有什么意义呢?

我还需要编写这个过滤器并手动转换它。

我认为应该有一种简单的方法可以在数据库级别应用偏移量,还是我错了?

编辑

一些可能有用的信息,型号:

class User(UserMixin, Base):
    __tablename__ = 'users'
    date_added = Column(DateTime(timezone=True), nullable=False)

它在数据库中的样子:

这是我如何在 jinja2/html:

中加载它的示例
{{ tenant.date_added.strftime('%d.%m.%Y um %H:%M Uhr') }}

首先,你完全在数据库内部处理这个是对的。处理时区时,或者始终使用timestamp with time zone并让数据库处理转换等,使用timestamp without time zone自始至终,存储 UTC 时间戳并让应用程序处理时区处理。混合这两者通常不是一个好主意。

PostgreSQL 在内部将 timestamp with time zone 存储为 UTC 时间戳。转换为字符串后,例如向客户端发送数据时,数据转换为会话时区,由timezone参数配置

timezone 设置为 ALTER DATABASE 将更改设置 所有未来会话 ,也就是说,您必须断开连接并重新连接才能获得新设置生效。

但是,每个会话都可以免费(并鼓励)使用 SET 命令或 set_config 函数更改 timezone,这决定了时间戳将是哪个时区转换。使用 SHOW timezone 查看您的当前设置。

如果您存储的时间戳没有明确的时区(如 2019-02-01 12:00:00),它将被解释为您当前的会话时区。因此,如果那是 Europe/Berlin,内部存储的 UTC 时间戳将是 2019-02-01 11:00:00 UTC。现在,如果您 SELECT 该值,它将显示为 2019-02-01 12:00:00+01,因为那是您当前的时区偏移量。如果更改timezone,相同的值将显示不同。