PostgreSQL存储什么时区信息?

时间:2019-02-08 10:07:17

标签: postgresql timestamp-with-timezone

PostgreSQL文档相当详尽且有用:

https://www.postgresql.org/docs/9.2/datatype-datetime.html#DATATYPE-TIMEZONES

但在一个相当有用的地方似乎忽略了清晰度,在这种情况下,可能需要保证和提供帮助。阅读了文档以及各种相关的stackoverflow问题和响应后,我怀疑以下内容是否正确:

  

PostgreSQL数据类型timestamp with timezone存储日期和   时间和utcoffset(+ ve在格林威治以东)

我会进一步推断并怀疑是真的

  

PostgreSQL数据类型timestamp with timezone存储日期和   时间和utcoffset(+ ve在格林威治以东)到分钟分辨率。

我的问题与这些推论有关。它们是否正确?如果可以,可以转发哪些证据以进行确认,如果不正确,可以转发哪些证据。

这很有趣的主要原因是,如果当然为true,则接受表pg_timezone_names中按名称或缩写表示的时区的PostgreSQL仅存储UTC偏移量,从而丢失DST信息。

意思是,要使将来的实际时区名称(在表pg_timezone_names中定义)可供读者使用,必须将其明确地与timestamp with timezone一起存储在旁边的列中。 / p>

现在让我感兴趣的主要原因是,我想到了我认为是一种相当聪明的渲染时间的方式,可以记录地球上任何地方的事件发生时间。即,如果记录的时间在用户当前时区中,则将其报告为原始日期/时间(无时区信息),并且仅在与读者不同的时区中报告时区信息(即使如此,时区名称可能比UTC偏移对用户更友好)。

如果我想在网站上实现此类上下文相关的呈现,似乎我将不得不在事件时间(以及我存储的任何其他时区已知的日期/时间)旁边存储时区名称。

但是我很不容易在推理而不是知识的基础上做出这样的承诺,并且希望有一些证据支持或矛盾这些推理。

1 个答案:

答案 0 :(得分:2)

您的假设都是错误的:

PostgreSQL将timestamp with time zone存储为8字节整数,其中包含与2000-01-01 00:00:00 UTC的偏移量(以微秒为单位)。

因此它既不存储时区,也不精确1分钟。

转换为字符串后,时间戳将根据timezone参数的当前设置进行格式化。

因此,如果您需要记住时区并使用AT TIME ZONE表达式将时间戳转换为正确的时区,则必须分别存储时区。

您要求提供文档参考。其中一部分是here

/*
 * Timestamp represents absolute time.
[...]
 * Timestamps, as well as the h/m/s fields of intervals, are stored as
 * int64 values with units of microseconds.  (Once upon a time they were
 * double values with units of seconds.)

在同一文件中找到

/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
#define UNIX_EPOCH_JDATE        2440588 /* == date2j(1970, 1, 1) */
#define POSTGRES_EPOCH_JDATE    2451545 /* == date2j(2000, 1, 1) */