PostgreSQL中带/不带时区的时间戳之间的区别

当数据types为WITH TIME ZONE而不是WITHOUT TIME ZONE时,PostgreSQL中的时间戳值是否以不同的方式存储? 可以用简单的testing用例来说明差异吗?

PostgreSQL文档中针对date/时间types介绍了这些差异。 是的, TIMETIMESTAMP的存储在一个WITH TIME ZONEWITHOUT TIME ZONE之间有所不同。

文档中具体介绍了这些数据types的时区效果。 不同的是系统可以合理地知道这个值:

  • 将时区作为该值的一部分,该值可以在客户端呈现为本地时间。

  • 如果没有时区作为值的一部分,那么明显的默认时区是UTC,因此会为该时区显示。

行为根据至less三个因素而不同:

  • 客户端中的时区设置。
  • 数据types(即WITH TIME ZONEWITHOUT 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