PostgreSQL 存储什么时区信息?
What timezone information does PostgreSQL store?
PostgreSQL 文档相当详尽且有用:
https://www.postgresql.org/docs/9.2/datatype-datetime.html#DATATYPE-TIMEZONES
但似乎忽略了一个相当有用的点,在这个点上,清晰可能是必要的和有帮助的。阅读文档和各种相关的 Whosebug 问题和回复后,我怀疑以下内容是否属实:
The PostgreSQL datatype timestamp with timezone
stores a date and
time and a utcoffset (+ve being east of Greenwich)
我会进一步推断并怀疑:
The PostgreSQL datatype timestamp with timezone
stores a date and
time and a utcoffset (+ve being east of Greenwich) to minute resolution.
我的问题与这些推论有关。它们是否正确,如果正确,可以转发哪些证据来证实它们,如果不正确,可以转发哪些相反的证据。
这很有趣的主要原因当然是因为如果为真,那么 PostgreSQL 按名称或缩写接受存储在 table pg_timezone_names
中的时区仅存储 UTC 偏移量,从而丢失 DST信息。
意思是,要使实际的时区名称(在 table pg_timezone_names
中定义)在将来对 reader 可用,它必须明确存储在 [= 旁边10=] 在它旁边的一列中。
我现在对此感兴趣的主要原因是,我想到了一种相当聪明的渲染时间的方法,可以记录地球上任何地方的事件时间。也就是说,如果记录的时间在用户当前时区,则将其报告为天真的 date/time(无时区信息),并且仅当它在与 readers 不同的时区时,才报告时区信息(即便如此,时区名称可能比 UTC 偏移量对用户更友好)。
如果我想在网站上实现这种上下文敏感的渲染,我似乎必须在我的事件时间旁边存储时区名称(以及我存储的任何其他时区感知 date/time)。
但我觉得基于推论而不是知识做出这样的承诺并不自在,我想要一些证据来支持或反驳这些推论。
你的两个假设都是错误的:
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) */
PostgreSQL 文档相当详尽且有用:
https://www.postgresql.org/docs/9.2/datatype-datetime.html#DATATYPE-TIMEZONES
但似乎忽略了一个相当有用的点,在这个点上,清晰可能是必要的和有帮助的。阅读文档和各种相关的 Whosebug 问题和回复后,我怀疑以下内容是否属实:
The PostgreSQL datatype
timestamp with timezone
stores a date and time and a utcoffset (+ve being east of Greenwich)
我会进一步推断并怀疑:
The PostgreSQL datatype
timestamp with timezone
stores a date and time and a utcoffset (+ve being east of Greenwich) to minute resolution.
我的问题与这些推论有关。它们是否正确,如果正确,可以转发哪些证据来证实它们,如果不正确,可以转发哪些相反的证据。
这很有趣的主要原因当然是因为如果为真,那么 PostgreSQL 按名称或缩写接受存储在 table pg_timezone_names
中的时区仅存储 UTC 偏移量,从而丢失 DST信息。
意思是,要使实际的时区名称(在 table pg_timezone_names
中定义)在将来对 reader 可用,它必须明确存储在 [= 旁边10=] 在它旁边的一列中。
我现在对此感兴趣的主要原因是,我想到了一种相当聪明的渲染时间的方法,可以记录地球上任何地方的事件时间。也就是说,如果记录的时间在用户当前时区,则将其报告为天真的 date/time(无时区信息),并且仅当它在与 readers 不同的时区时,才报告时区信息(即便如此,时区名称可能比 UTC 偏移量对用户更友好)。
如果我想在网站上实现这种上下文敏感的渲染,我似乎必须在我的事件时间旁边存储时区名称(以及我存储的任何其他时区感知 date/time)。
但我觉得基于推论而不是知识做出这样的承诺并不自在,我想要一些证据来支持或反驳这些推论。
你的两个假设都是错误的:
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) */