如何在 postgresql 中更新带有时区的日期?

How to update a date with a time zone in postgresql?

我想用时区(+2 小时)更新日期,但它最终为 UTC(0 小时)

日期类型是'timestamp-with-timezone'

查询...

update table set date = '2022-05-25 13:28+02:00'

最终会在数据库中变成这样。

2022-05-25 11:28:00+00

这是怎么回事?

tl;博士

没有错。 Postgres 以 UTC 格式存储 TIMESTAMP WITH TIME ZONE 的值,与 UTC 的偏移量始终为零。任何提交的偏移量或区域都用于调整为 UTC。

详情

Date type is 'timestamp-with-timezone'

标准 SQL 和 Postgres 中都没有这种类型。

我假设你的意思是 TIMESTAMP WITH TIME ZONE

it ends up as UTC (0 hours)

阅读精美手册。您看到的是记录在案的行为。

Postgres 始终将值存储在 UTC 类型 TIMESTAMP WITH TIME ZONE 的列中,即偏移量为零 hours-minutes-seconds.

随输入提供的任何时区或偏移量都用于调整为 UTC。然后丢弃提供的区域或偏移量。

所以类型的名称 TIMESTAMP WITH TIME ZONE 是用词不当。首先,SQL 的作者考虑的是偏移量,而不是实时时区。其次,任何提交的时区都存储。提交的区域用于调整然后丢弃。

如果您需要跟踪原始偏移量或区域,请添加一个额外的列。您必须添加代码来存储偏移量或时区名称。

update table set date = '2022-05-25 13:28+02:00' will end up as this in the database. 2022-05-25 11:28:00+00 What's wrong here?

没有错。这是一个特性,而不是一个错误。这两个字符串代表完全相同的同时时刻。


仅供参考,数据库引擎在处理 date-time 类型和行为方面 差异很大

有些像 Postgres 对 TIMESTAMP WITH TIME ZONE 所做的那样,调整为 UTC,然后丢弃任何提供的时区或偏移量。有些人可能不会。

SQL 标准几乎没有涉及 date-time 处理的主题。它声明了几种类型,并且由于未完全覆盖所有情况而做得很差。而且标准忽略了定义行为。

因此,在处理数据库工作时要非常小心 date-time。仔细阅读特定数据库引擎的文档。不要做假设。 运行 实验来验证您的理解。并且知道为 date-time 编写可移植 SQL 代码可能不可行。