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

时间:2019-02-01 10:07:26

标签: postgresql timestamp-with-timezone

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

但是我想跳过这一步。

通常PostgreSQL将日期时间对象保存在UTC中。

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

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

SHOW timezone;告诉我它的Europe/Berlin有用。

但是Postgres所做的是,它仍然将日期时间保存为UTC,但是对于欧洲/柏林有+1偏移,这实际上不是问题。

我假设在读取日期时间对象时,Postgres将应用偏移量并返回欧洲/柏林时间,但事实并非如此。它仍然会返回UTC时间,那么更改时区又有什么意义呢?

我仍然需要编写此过滤器并手动对其进行转换。

我认为应该有一种简单的方法来在数据库级别应用偏移量,否则我错了吗?

编辑

某些信息可能会对模型有所帮助:

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

它在数据库中的外观:

enter image description here

这是我如何在jinja2 / html中加载它的示例:

{{ tenant.date_added.strftime('%d.%m.%Y um %H:%M Uhr') }}

1 个答案:

答案 0 :(得分:0)

首先,您完全可以在数据库中完全处理此问题。在处理时区时,要么始终使用timestamp with time zone并让数据库处理转换,并且始终使用timestamp without time zone,存储UTC时间戳和让应用程序处理时区处理。混合使用这两种方法通常不是一个好主意。

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

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

但是,每个会话都可以使用timezone命令或SET函数自由(并鼓励)更改set_config,这决定了将时间戳转换到哪个时区。使用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,则相同的值将以不同的方式显示。