可以说我有一个带时区的时间戳记存储在我的PostgreSQL数据库中。像这样:
2003-04-12 04:05:06.814191 America/New_York
在读取此数据时,数据库会以GMT返回调整后的时间以标准化所有读取的时间戳,还是只是按原样返回它?
我问这个问题的原因是我创建了一个带有记录的表,其中每个记录都有一个timestamp列。我继续为不同的记录提供不同的时区。当我查询该表并尝试按timestamp列进行排序时,时区似乎对排序没有任何影响。这是设计使然吗?
我的结果示例:
1954-06-27 08:44:01.963454 Asia/Baghdad
1954-06-27 08:44:01.963454 GMT
1954-06-27 08:44:01.963454 Europe/Paris
1954-06-27 08:44:01.963454 Asia/Baghdad
1954-06-27 08:44:01.963454 America/New_York
1954-06-27 08:44:01.963454 America/New_York
1954-06-27 08:44:01.963454 America/New_York
1954-06-27 08:44:01.963454 GMT
1954-06-27 08:44:01.963454 America/New_York
1954-06-27 08:44:01.963454 America/New_York
1954-06-27 08:44:01.963454 Europe/Paris
1954-06-27 08:44:01.963454 America/New_York
1954-06-27 08:44:01.963454 Asia/Dhaka
1954-06-27 08:44:01.963454 GMT
1954-06-27 08:44:01.963454 GMT
1954-06-27 08:44:01.963454 Asia/Damascus
1954-06-27 08:44:01.963454 GMT
1954-06-27 08:44:01.963454 Asia/Damascus
1954-06-27 08:44:01.963454 America/New_York
1954-06-27 08:44:01.963454 Asia/Dhaka
1954-06-27 08:44:01.963454 Asia/Baghdad
1954-06-27 08:44:01.963454 Europe/Paris
1954-06-27 08:44:01.963454 Europe/Paris
1954-06-27 08:44:01.963454 Asia/Baghdad
1954-06-27 08:44:01.963454 Asia/Baghdad
所有这些记录的日期和时间都相同,并且不同的时区对顺序没有影响。
为了更清楚一点,我实际上是将这些时间戳记作为字符串存储在名为data
的JSONb列中,其键为datetime
,即:
data = {
"datetime" : "2003-04-12 04:05:06.814191 America/New_York",
.....
}
在排序和过滤期间,我将其强制转换为时间戳。像这样:
"(data->>'datetime')::timestamp"
答案 0 :(得分:2)
PostgreSQL的“带时区的时间戳”类型实际上并未在每个记录中存储时区偏移量。它只是在内部将所有内容标准化为UTC。
“带时区的时间戳”的要点是,由于存储的值是在已知的时区中表示的,因此它明确地表示了特定的时间点。备选方案“没有时区的时间戳”是模棱两可的,因为它有时间,但没有说出它所在的时区-记录今天可能说中午,但是格林威治中午是中午吗?纽约中午?东京中午? “带时区”类型避免了该问题,因为该时区始终为格林威治。
(作为比较:我相信Oracle具有一个“带有时区的时间戳”,实际上在每个记录中存储一个偏移量,以及一个“带有本地时区的时间戳”,该规范将所有内容标准化到服务器的时区,以避免必须存储每个时区。 -记录偏移量。PostgreSQL的“带时区的时间戳”的名称与前者类似,但行为与后者类似。)
但是,听起来您实际上并没有在表中存储“带时区的时间戳”;您实际上是存储一个字符串,并作为timestamp
的一部分强制转换为select
。 timestamp
关键字本身指的是“无时区”变体(SQL标准要求),而PostgreSQL文档说:
在已确定为
timestamp without time zone
的文字中,PostgreSQL将静默忽略任何时区指示。也就是说,结果值是从输入值中的日期/时间字段派生的,并且未针对时区进行调整。
我希望转换也一样,尽管如果是这样,还不清楚为什么您的输出(timestamp
值)包含TZ名称。但是您可能想强制转换为timestamptz
,或者可能创建一个单独的timestamptz
列(以便可以为值建立索引)。