回答:
違いは、日付/時刻型のPostgreSQLドキュメントで説明されています。はい、の治療TIMEまたはTIMESTAMP1との間で異なりますWITH TIME ZONEかWITHOUT TIME ZONE。値の保存方法には影響しません。それらの解釈方法に影響します。
これらのデータ型に対するタイムゾーンの影響については、特にドキュメントで説明されています。違いは、システムが値について合理的に知ることができるものから生じます。
値の一部としてタイムゾーンを使用すると、値をクライアントでローカル時間としてレンダリングできます。
値の一部としてタイムゾーンがない場合、明らかにデフォルトのタイムゾーンはUTCであるため、そのタイムゾーンでレンダリングされます。
動作は、少なくとも3つの要因によって異なります。
WITH TIME ZONEまたはWITHOUT 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)
timestamp with time zoneとtimestamp without time zone、Postgresのではない*ない実際のタイムゾーン情報を格納します。これは、データタイプのドキュメントページで一目で確認できます。どちらのタイプも同じ数のオクテットを使用し、値の保存範囲があるため、タイムゾーン情報を保存するスペースがありません。ページのテキストはこれを確認します。誤解の一部:「tzなし」は「データ挿入時にオフセットを無視する」を意味し、「tz付き」は「オフセットを使用してUTCに調整する」ことを意味します。
参照しているPostgreSQLのドキュメントよりもわかりやすく説明するようにしています。
どちらのTIMESTAMPバリアントも、名前が示すとおり、タイムゾーン(またはオフセット)を保存しません。違いは、格納形式自体ではなく、格納されたデータの解釈(および目的のアプリケーション)にあります。
TIMESTAMP WITHOUT TIME ZONEローカルの日付時刻(別名、壁掛けカレンダーの日付と壁掛け時計の時刻)を格納します。PostgreSQLが認識できる限り、そのタイムゾーンは指定されていません(アプリケーションがそれを知っている場合もあります)。したがって、PostgreSQLは入力または出力でタイムゾーン関連の変換を行いません。値がとしてデータベースに入力された場合、'2011-07-01 06:30:30'後で表示するタイムゾーンには何も表示されず、2011年、07日、01日、06時間、30分、30秒(ある形式)と表示されます。また、任意のオフセットまたはあなたが入力で指定した時間帯は、PostgreSQLによって無視され、そう'2011-07-01 06:30:30+00'と'2011-07-01 06:30:30+05'ばかり同じです'2011-07-01 06:30:30'。Java開発者の場合:に似ていjava.time.LocalDateTimeます。
TIMESTAMP WITH TIME ZONEUTCタイムライン上のポイントを保存します。見た目(時間、分など)はタイムゾーンによって異なりますが、常に同じ「物理的な」瞬間(実際の物理的なイベントの瞬間など)を指します。入力は内部でUTCに変換され、それが格納されます。そのため、入力のオフセットは既知である必要があるため、入力に明示的なオフセットまたはタイムゾーン(など'2011-07-01 06:30:30')が含まれていない場合、PostgreSQLセッションの現在のタイムゾーンであると想定されます。それ以外の場合、明示的に指定されたオフセットまたはタイムゾーンが使用されます。 (のように'2011-07-01 06:30:30+05')。出力は、PostgreSQLセッションの現在のタイムゾーンに変換されて表示されます。Java開発者の場合:これはjava.time.Instant(解像度は低くなりますが)に似ていますが、JDBCおよびJPA 2.2では、それをjava.time.OffsetDateTime(java.util.Dateまたはjava.sql.Timestamp もちろん)。
両方のTIMESTAMPバリエーションがUTC日時を格納すると言う人もいます。ちょっと、でも私の意見ではそのように言うのは紛らわしいです。TIMESTAMP WITHOUT TIME ZONEはのように格納さTIMESTAMP WITH TIME ZONEれ、UTCタイムゾーンでレンダリングされ、たまたまローカルの日付時刻と同じ年、月、日、時間、分、秒、マイクロ秒が与えられます。しかし、それはUTC解釈が言うタイムライン上のポイントを表すことを意味するのではなく、それはローカルの日時フィールドがエンコードされる方法にすぎません。(リアルタイムゾーンはUTCではないため、タイムライン上のドットのクラスターです。それが何であるかはわかりません。)
TIMESTAMP WITH TIME ZONEとして取得しても問題はありませんInstant。どちらもUTCのタイムライン上のポイントを表します。より自己文書化されているためInstant、私の意見では、OffsetDateTimeA が優先されTIMESTAMP WITH TIME ZONEます。A は常にデータベースからUTCとして取得され、Instantは常にUTCであるため自然な一致ですが、OffsetDateTimeは他のオフセットを運ぶことができます。
OffsetDateTime、マッピングされたJava型としてのみ言及しています。Instanceまだどこかで非公式にサポートされているかどうかはわかりません。
'2011-07-01 06:30:30+00'と'2011-07-01 06:30:30+05' 無視されますが、私はやることができるよinsert into test_table (date) values ('2018-03-24T00:00:00-05:00'::timestamptz);、それは正しくUTCに変換します。ここで、日付はタイムゾーンなしのタイムスタンプです。タイムゾーン付きのタイムスタンプの主な値が何であるかを理解しようとしていますが、問題があります。
::timestamptzます。これで、文字列をTIMESTAMP WITH TIME ZONEに変換しWITHOUT TIME ZONE、さらにに変換すると、セッションタイムゾーン(UTC)から見た、その瞬間の「ウォールカレンダー」の日とウォールクロック時間が格納されます。それでも、オフセットが指定されていないローカルタイムスタンプのみになります(ゾーンなし)。
これは役立つはずの例です。タイムゾーンを持つタイムスタンプがある場合、そのタイムスタンプを他のタイムゾーンに変換できます。基本のタイムゾーンがない場合、正しく変換されません。
SELECT now(),
now()::timestamp,
now() AT TIME ZONE 'CST',
now()::timestamp AT TIME ZONE 'CST'
出力:
-[ RECORD 1 ]---------------------------
now | 2018-09-15 17:01:36.399357+03
now | 2018-09-15 17:01:36.399357
timezone | 2018-09-15 08:01:36.399357
timezone | 2018-09-16 02:01:36.399357+03
timestampをtimestamptz意味し、理解する必要があります。timestamptz絶対時刻(UTC)をtimestamp意味しますが、特定のタイムゾーンで時計が何を示したかを示します。したがって、timestamptzタイムゾーンに変換するときに、この絶対的な時点でニューヨークの時計が何を示していたのでしょうか。一方、を「変換」するとき、ニューヨークの時計がxを示した絶対的な時点は何だったのかとtimestamp尋ねています。
AT TIME ZONE構築物は、すでに理解していても、独自のティーザー脳であるWITH対のWITHOUT TIME ZONEタイプを。したがって、それらを説明するための好奇心の強い選択です。(:(タイムスタンプをタイムスタンプに、またはその逆にAT TIME ZONE変換します...正確には明らかではありません。)WITH TIME ZONEWITHOUT TIME ZONE
now()::timestamp AT TIME ZONE 'CST'ゾーン 'CST'のクロックが、ローカルクロックが現在表示している時間をいつ表示するかを除いて、意味がありません