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
ます。
おそらく、入力値のあいまいさを補うために、「タイムゾーン」列 (P
またはM
) を使用したと思われます。TIMESTAMP WITHOUT TIME ZONE
原則として、タイムスタンプを保存したタイムゾーンと同じ相対タイム ゾーンにいる場合は、同じ値が返されるはずですUS/Pacific
。ゾーン、あなたは戻るべきです。ただし、これは相対値に曖昧性がない場合にのみ有効です。2013-11-03 03:00:00
P
2013-11-03 03:00:00
ここでの最初の例の問題は、すでにいくつかのあいまいさがあることです:
タイムスタンプ: 2013-11-03 01:00:00 タイムゾーン: "P" は次のようになります: 2013-11-03 01:00:00-07
2013-11-03 01:00:00
US/Pacific
は、タイム ゾーン内の 2 つの異なる瞬間を表すことができるため、 と だけ2013-11-03 01:00:00
で"P"
は、回復できない情報を既に失っています。
その時点での DST 設定に応じて「-08」と「-07」の間で変更したいだけの場合、これは自動的に行われますがTIMESTAMPTZ
、最初にa を使用する必要がありました。あなたが表現していた時間の正確な瞬間。
次の例では、最初のタイム ゾーンが保持されているため、'-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 |
残念ながら、2 つのフィールドだけで DST の変更を処理する方法はありません。
これらの問題をよりよく理解するために、PostgreSQL マニュアルの日付/時刻型のセクションを読むだけでなく、AT TIME ZONE
ドキュメントの表の「戻り値の型」列に注意を払うことは確かに価値があります。