简体   繁体   English

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

[英]PostgreSQL timestamp with timezone apply offset when reading

First of all I know there are a lot threads about this and I could use the solutions there, fe write a python function which converts datetime object to the timezone I need and add this as a filter to jinja2. 首先,我知道这里有很多线程,可以在那里使用解决方案,例如,编写一个Python函数将datetime对象转换为所需的时区,并将其作为过滤器添加到jinja2。

But I wanted to skip this step. 但是我想跳过这一步。

Usually PostgreSQL saves datetime objects in UTC . 通常,PostgreSQL将日期时间对象保存在UTC

What I did is: I changed the default timezone which postgreSQL uses to save datetime objects to: Europe/Berlin 我所做的是:我将postgreSQL用来将日期时间对象保存到的默认时区更改为: Europe/Berlin

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

This worked, SHOW timezone; 这工作, SHOW timezone; tells me its Europe/Berlin . 告诉我它的Europe/Berlin

But what Postgres does, it still saves the datetime as UTC, but with a +1 offset for Europe/Berlin, which is actually not a problem. 但是Postgres所做的是,它仍然将日期时间保存为UTC,但是对于欧洲/柏林有+1偏移,这实际上不是问题。

I assumed that when reading the datetime object, Postgres would apply the offset and return the Europe/Berlin time, but it doesn't. 我假设读取日期时间对象时,Postgres将应用偏移量并返回欧洲/柏林时间,但事实并非如此。 It still returns the UTC time, so whats the point in changing the timezone? 它仍然会返回UTC时间,那么更改时区又有什么意义呢?

I still need to write this filter and manually convert it. 我仍然需要编写此过滤器并手动对其进行转换。

I think there should be a simple way to apply the offset on DB level, or am I wrong? 我认为应该有一种简单的方法可以在数据库级别应用偏移量,否则我错了吗?

EDIT 编辑

Some information, which might help, the model: 一些信息可能会对模型有所帮助:

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

How it looks in the DB: 它在数据库中的外观:

在此处输入图片说明

And here is an example how I load it in jinja2/html: 这是我如何在jinja2 / html中加载它的示例:

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

First, you are right to handle this completely inside the database. 首先,您完全可以在数据库中完全处理此问题。 When dealing with time zones, either use timestamp with time zone throughout and let the database handle conversions and such, or use timestamp without time zone throughout, store UTC timestamps and let the application deal with time zone handling. 处理时区时, 要么在整个timestamp with time zone使用timestamp with time zone并让数据库处理转换等, 要么在整个timestamp without time zone使用timestamp without time zone时间戳,存储UTC时间戳并让应用程序处理时区。 Mixing these two is usually not a good idea. 混合这两个通常不是一个好主意。

PostgreSQL internally stores a timestamp with time zone as a timestamp in UTC. PostgreSQL内部存储timestamp with time zone的时间戳记作为UTC中的时间戳记。 Upon conversion to a string , eg when data are sent to the client, the data is converted to the session time zone , which is configured by the timezone parameter. 在转换为字符串时(例如,当数据发送到客户端时),数据将转换为会话时区 ,该会话时区timezone参数配置。

Setting timezone with ALTER DATABASE will change the setting for all future sessions , that is, you have to disconnect and reconnect for the new setting to take effect. 使用ALTER DATABASE设置timezone将更改以后所有会话的设置,也就是说,您必须断开连接并重新连接才能使新设置生效。

However, every session is free (and encouraged) to change timezone using the SET command or the set_config function, and this determines to which time zone the timestamps will be converted. 但是,每个会话都可以使用SET命令或set_config函数自由(并鼓励)更改timezone ,这决定了将时间戳转换到哪个时区。 Use SHOW timezone to see your current setting. 使用SHOW timezone查看您的当前设置。

If you store a timestamp without an explicit time zone (like 2019-02-01 12:00:00 ), it will be interpreted in your current session time zone. 如果您存储的时间戳没有明确的时区(例如2019-02-01 12:00:00 ),它将在您当前的会话时区中进行解释。 So if that is Europe/Berlin , the UTC timestamp stored internally will be 2019-02-01 11:00:00 UTC . 因此,如果是Europe/Berlin ,则内部存储的UTC时间戳将为2019-02-01 11:00:00 UTC Now if you SELECT the value, it will be displayed as 2019-02-01 12:00:00+01 , because that is your current time zone offset. 现在,如果您SELECT该值,它将显示为2019-02-01 12:00:00+01 ,因为这是您当前的时区偏移量。 If you change timezone , the same value will be displayed differently. 如果更改timezone ,则相同的值将以不同的方式显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM