TIMESTAMP WITHOUT TIME ZONE
和TIMESTAMP WITH TIME ZONE
(TIMESTAMPTZ
)之間的差異可能是非常棘手的問題,如果你考慮他們的名字。 (實際上,規範似乎有足夠的混淆,因此各種RDBMS以不同的方式實現它。)
在PostgreSQL中,兩種類型都不存儲存儲時值的時區,但TIMESTAMPTZ
將值存儲爲基於UTC參考的精確時刻,而TIMESTAMP WITHOUT TIME ZONE
總是相對的。
- 當被查詢時,一個
TIMESTAMPTZ
將被調整爲表示在作爲初始存儲的同一時刻(在取其世界這是一部分)作爲瞬間這將是在當前時區配置用於通過所述客戶端。
- A
TIMESTAMP WITHOUT TIME ZONE
將始終與客戶端配置的時區相同,即使您查詢的時區不同:由2013-11-03 03:00:00
表示的時刻將不明確,並取決於客戶端設置。
想必,你與你的TIMESTAMP WITHOUT TIME ZONE
使用你的「時區」列(P
或M
),以補償輸入價值的不確定性。
原則上,如果您的時區與存儲時間戳的時區相同,則應該返回相同的值,因此如果您已將客戶端設置爲US/Pacific
時區,已在P
時區儲存2013-11-03 03:00:00
,您應該返回2013-11-03 03:00:00
。但是,這隻有在相對值沒有歧義時纔有效。
在你的第一個例子這裏的問題是,已經有一些模糊:
時間戳:2013年11月3日01:00:00時區:「P」將成爲:2013年11月3日 01:00:00-07
2013-11-03 01:00:00
可以表示時間兩個不同時刻在US/Pacific
時區,所以只有2013-11-03 01:00:00
和"P"
,你已經失去了信息,你將無法恢復。
如果您只是想根據當時的DST設置在'-08'和'-07'之間進行切換,這將自動完成,但您應該使用TIMESTAMPTZ
第一個地方,準確地說,你在哪個時間表現。
這裏就是初始時間區保持一個例子,所以你可以看到之間的 '-08' 和改變 '-07':
SET time zone 'US/Pacific';
SELECT t AS "Date/Time for US/Pacific",
t AT time zone 'UTC' "Date/Time in UTC"
FROM (VALUES
('2013-11-03 00:00:00-07'::timestamptz),
('2013-11-03 01:00:00-07'::timestamptz),
('2013-11-03 02:00:00-07'::timestamptz),
('2013-11-03 03:00:00-07'::timestamptz)) AS v(t);
結果:
| DATE/TIME FOR US/PACIFIC | DATE/TIME IN UTC |
|--------------------------|---------------------|
| 2013-11-03 00:00:00-07 | 2013-11-03 07:00:00 |
| 2013-11-03 01:00:00-07 | 2013-11-03 08:00:00 |
| 2013-11-03 01:00:00-08 | 2013-11-03 09:00:00 |
| 2013-11-03 02:00:00-08 | 2013-11-03 10:00:00 |
不幸,只有兩個字段無法處理DST更改。
當然值得您閱讀Date/Time types section of the PostgreSQL manual,並注意AT TIME ZONE
documentation表中的「返回類型」列,以便更好地理解這些問題。
您的問題在編輯後更有意義,但根本問題依然存在。 「2013-11-03 01:00:00」仍然不明確:可能是「2013-11-03 00:59:00-07」或分鐘後的分鐘「2013-11-03 01:59:00」 00-07" 。 – Bruno