PostgreSQL中带/不带时区的时间戳之间的区别
当数据types为WITH TIME ZONE
而不是WITHOUT TIME ZONE
时,PostgreSQL中的时间戳值是否以不同的方式存储? 可以用简单的testing用例来说明差异吗?
PostgreSQL文档中针对date/时间types介绍了这些差异。 是的, TIME
或TIMESTAMP
的存储在一个WITH TIME ZONE
或WITHOUT TIME ZONE
之间有所不同。
文档中具体介绍了这些数据types的时区效果。 不同的是系统可以合理地知道这个值:
-
将时区作为该值的一部分,该值可以在客户端呈现为本地时间。
-
如果没有时区作为值的一部分,那么明显的默认时区是UTC,因此会为该时区显示。
行为根据至less三个因素而不同:
- 客户端中的时区设置。
- 数据types(即
WITH TIME ZONE
或WITHOUT TIME ZONE
)的值。 - 是否用特定的时区指定值。
以下是涵盖这些因素组合的示例:
foo=> SET TIMEZONE TO 'Japan'; SET foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP; timestamp --------------------- 2011-01-01 00:00:00 (1 row) foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE; timestamptz ------------------------ 2011-01-01 00:00:00+09 (1 row) foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP; timestamp --------------------- 2011-01-01 00:00:00 (1 row) foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE; timestamptz ------------------------ 2011-01-01 06:00:00+09 (1 row) foo=> SET TIMEZONE TO 'Australia/Melbourne'; SET foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP; timestamp --------------------- 2011-01-01 00:00:00 (1 row) foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE; timestamptz ------------------------ 2011-01-01 00:00:00+11 (1 row) foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP; timestamp --------------------- 2011-01-01 00:00:00 (1 row) foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE; timestamptz ------------------------ 2011-01-01 08:00:00+11 (1 row)
这是一个应该帮助的例子。 如果您有时区的时间戳,则可以将该时间戳转换为任何其他时区。 如果你没有一个基准时区,它将不会被正确转换。
SELECT now(), now()::timestamp, now() AT TIME ZONE 'CST', now()::timestamp AT TIME ZONE 'CST'
SELECT MAX('2017-07-06 12:20:48.446+00') - MIN('2017-06-06 12:20:48.446+00') as time_to_take from table_name