Postgres 通过时区转换防止时间戳

Posted

技术标签:

【中文标题】Postgres 通过时区转换防止时间戳【英文标题】:Postgres prevent timestamp with timezone conversion 【发布时间】:2016-06-20 03:13:50 【问题描述】:

我有一张表,用于存储带时区的 iso 日期。我意识到日期应该“始终”存储为 utc,但我对该规则有一个例外。时间戳与它们运行的​​服务器没有任何关系。我希望能够像这样存储 iso 日期: 2016-03-06T01:15:52-06:00 无论服务器的时区如何,我都希望时间戳返回为: 2016-03-06T01:15:52-06:00

目前,如果我插入 iso 日期,它会自动将其转换为服务器时区。我上面的日期被转换为: 2016-03-06 07:15:52+00(服务器是UTC)

我唯一能想到的是将时区偏移存储在单独的列中,将我的日期存储为 utc,然后使用偏移列进行转换,非常混乱。当然有一种方法可以将我的日期存储在一个列中并按照最初创建的方式将其取出?

【问题讨论】:

当然有一种方法可以将我的日期存储在一个列中,并按照最初创建的方式将其取出:是的,text 类型。 听起来好像你在使用timestamp with time zone。如果您不希望它转换,请改用timestamp @DanielVérité 是的,但这会阻止我使用任何日期函数。 @a_horse_with_no_name 我想存储我的时区。 “无时区”完全丢弃任何时区。 postgres 中似乎没有一种数据类型可以真正存储时间戳和任意时区。 timestamp with time zone 存储时区。如果需要,请使用 timestamp 并将时区存储在单独的列中。 【参考方案1】:

您提出的解决方案是正确的。或者更准确地说,它是几种正确的实现方式之一。以下任何一项都可以:

将 UTC 时间戳存储在一个字段中,将偏移量存储在另一个字段中。 将本地时间戳存储在一个字段中,将偏移量存储在另一个字段中。 将本地date 存储在一个字段中,并将time with time zone 存储在另一个字段中。 (虽然time with time zone 通常不鼓励......) 将 UTC 时间戳存储在一个字段中,将本地时间戳存储在另一个字段中。

目前最简单的是第一个,你已经提出了。

我会避免在 text 字段中存储时间戳,因为它们往往不是很有效的搜索。

另请注意 - 如果您来自 SQL Server 背景,您可能会想起它的 datetimeoffset 类型,它在字段中存储本地日期时间和偏移量,并在索引期间使用等效的 UTC。通常认为 Postgres 和 mysqltimestamp with time zone 会有相同的行为,但事实并非如此。他们只需使用 session 时区来转换为/从 UTC 转换。 SQL Server 没有会话时区的概念,因此存在差异。

请务必阅读this part of the Postgres docs。

【讨论】:

这就是我所害怕的。谢谢:)

以上是关于Postgres 通过时区转换防止时间戳的主要内容,如果未能解决你的问题,请参考以下文章

javascript + postgres:时区和时间戳的使用

Rails 和 Postgres:迁移到 change_colomn 时出现错误“无法强制转换为没有时区的时间戳”

使用 node-postgres 在 utc 中获取 Postgres“没有时区的时间戳”

在 Postgres 中创建表时将空列设置为带时区的时间戳

在带有 C 扩展名的 Postgres DB 中使用时区存储时间戳?

使用 Spring Data 的 postgres 中的时间戳出错:列 $COLUMN_NAME 是没有时区的时间戳类型,但表达式是 bytea 类型