PostgreSQL 提供兩種存儲時間戳的數據類型: 不帶時區的 TIMESTAMP
和帶時區的 TIMESTAMPTZ
。sql
TIMESTAMP
數據類型能夠同時存儲日期和時間,但它不存儲時區。這意味着,當修改了數據庫服務器所在的時區時,它裏面存儲的值不會改變。數據庫
TIMESTAMPTZ
數據類型在存儲日期和時間的同時還能正確處理時區。PostgreSQL 使用 UTC 值來存儲 TIMESTAMPTZ
數據。在向 TIMESTAMPTZ
字段插入值的時候,PostgreSQL 會自動將值轉換成 UTC 值,並保存到表裏。當從一個 TIMESTAMPTZ
字段查詢數據的時候,PostgreSQL 會把存儲在其中的 UTC 值轉換成數據庫服務器、用戶或當前鏈接所在的時區。服務器
TIMESTAMP
和 TIMESTAMPTZ
都使用8字節存儲空間。以下所示:post
SELECT typname, typlen FROM pg_type WHERE typname ~ '^timestamp'; typname | typlen -------------+-------- timestamp | 8 timestamptz | 8 (2 rows)
重要提示,TIMESTAMPTZ
並不會存儲時區,它只是了 UTC 值,而後會和當前時區進行轉換。spa
首先,建立一個含有 TIMESTAMP
和 TIMESTAMPTZ
的表:postgresql
CREATE TABLE timestamp_demo (ts TIMESTAMP, tstz TIMESTAMPTZ);
接下來,將數據庫服務器的時區設置爲 America/Los_Angeles
:code
SET timezone = 'America/Los_Angeles';
順便說一句,可使用 SHOW TIMEZONE
語句來顯示當前時區:blog
SHOW TIMEZONE;
而後,插入一些示例數據:get
INSERT INTO timestamp_demo (ts, tstz) VALUES ( '2016-06-22 19:10:25-07', '2016-06-22 19:10:25-07' );
最後,查詢:class
SELECT ts FROM timestampz_demo; ts | tstz ---------------------+------------------------ 2016-06-22 19:10:25 | 2016-06-22 19:10:25-07 (1 row)
再把時區設置爲 America/New_York
:
SET timezone = 'America/New_York';
再查詢一次,結果以下:
ts | tstz ---------------------+------------------------ 2016-06-22 19:10:25 | 2016-06-22 22:10:25-04 (1 row)
TIMESTAMP
類型字段的值不變,而 TIMESTAMPTZ
類型字段的值變成了當前時區下的時間。