关于时区:PostgreSQL改变没有时区的类型时间戳 – >带时区

PostgreSQL alter type timestamp without time zone -> with time zone

问题很简单:如果我已经在没有时区的列类型时间戳中有数据,如果我将类型设置为带时区的时间戳,postgresql对这些数据做了什么?


它将当前值保持在本地时间,并将时区设置为本地时间的偏移量:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE a(t TIMESTAMP WITHOUT TIME zone, t2 TIMESTAMP WITH TIME zone);
INSERT INTO a(t) VALUES ('2012-03-01'::TIMESTAMP);
UPDATE a SET t2 = t;
SELECT * FROM a;
          t          |           t2          
---------------------+------------------------
 2012-03-01 00:00:00 | 2012-03-01 00:00:00-08

ALTER TABLE a ALTER COLUMN t TYPE TIMESTAMP WITH TIME zone;
SELECT * FROM a;
           t            |           t2          
------------------------+------------------------
 2012-03-01 00:00:00-08 | 2012-03-01 00:00:00-08

根据Alter Table手册:

if [the USING clause is] omitted, the default conversion is the same as an assignment cast from old data type to new.

根据日期/时间类型的手册

Conversions between timestamp without time zone and timestamp with time zone normally assume that the timestamp without time zone value should be taken or given as timezone local time. A different time zone can be specified for the conversion using AT TIME ZONE.


最好明确指定时区。 比如说,如果您的时间戳应该是UTC(但没有时区),那么您应该警惕客户端或服务器的时区可能会弄乱这里的所有内容。 而是写:

1
ALTER TABLE a ALTER COLUMN t TYPE TIMESTAMP WITH TIME ZONE USING t AT TIME ZONE 'UTC'