sql >> データベース >  >> RDS >> PostgreSQL

Postgresでのタイムゾーン間の変換

    2つの例を説明しましょう:

    どちらの場合も、タイムゾーンUTC(つまり、SET timezone TO UTC)を想定しています。 。

    db=# SELECT timezone('US/Pacific', '2016-01-01 00:00');
          timezone
    ---------------------
     2015-12-31 16:00:00
    (1 row)
    

    これは、SELECT timezone('US/Pacific', '2016-01-01 00:00'::timestamptz)と同等です。 つまり、Postgresは文字列を暗黙的にtimestamptzに変換しました 。

    timezone 関数はtimestamp間を行ったり来たりします およびtimestamptz

    timestamptzを指定しているので 入力として、timestampを出力します 。つまり、絶対時点2016-01-01 00:00Zを変換しています。 US/Pacificの実時間まで 、つまり、ロサンゼルスの時計がその絶対的な時点で示したものです。

    例2では、​​逆のことを行っています。つまり、timestampを取得しています。 そしてそれをtimestamptzに変換します 。言い換えれば、私たちは尋ねています:ロサンゼルスの時計が2016-01-01 00:00を示した絶対的な時点は何でしたか ?

    あなたが言及する:

    '2016-01-01 00:00'::timestamp timestampです 、つまり壁時計。タイムゾーンの概念はありません。

    timestampの違いを完全には理解していないかもしれません およびtimestamptz 、ここで重要なのは。それらを実時間と考えてください。 、つまり、壁に掛かっている時計で世界のどこかに表示された時間、および絶対時間 、つまり私たちの宇宙の絶対時間。

    あなたがあなた自身の答えで作る例は完全に正確ではありません。

    SELECT ts FROM  (VALUES
    (timestamptz '2012-03-05 17:00:00+0') -- outputs 2012-03-05 17:00:00+00 --1
    ,(timestamptz '2012-03-05 18:00:00+1') -- outputs 2012-03-05 17:00:00+00 --2
    ,(timestamp   '2012-03-05 18:00:00+1') -- outputs 2012-03-05 18:00:00+00 --3
    ,(timestamp   '2012-03-05 11:00:00'  AT TIME ZONE '+6') -- outputs 2012-03-05 17:00:00+00 --4
    ,(timestamp   '2012-03-05 17:00:00'  AT TIME ZONE 'UTC') -- outputs 2012-03-05 17:00:00+00 --5
    ,(timestamp   '2012-03-05 17:00:00'::timestamp) -- outputs 2012-03-05 17:00:00+00 --6
    ,(timestamp   '2012-03-05 17:00:00'::timestamptz) -- outputs 2012-03-05 17:00:00+00 --7
        ) t(ts);
    

    あなたの例の問題は、単一の列で1つのデータセットを構築していることです。列は1つのタイプしか持てないため、各行(この場合は単一の値)は同じタイプ、つまりtimestamptzに変換されます。 、一部の値はtimestampとして計算されましたが (例:値3)。したがって、ここに追加の暗黙的な変換があります。

    例を個別のクエリに分割して、何が起こっているかを見てみましょう:

    例1

    db=# SELECT timestamptz '2012-03-05 17:00:00+0';
          timestamptz
    ------------------------
     2012-03-05 17:00:00+00
    

    ご存知かもしれませんが、timestamptz '2012-03-05 17:00:00+0' および'2012-03-05 17:00:00+0'::timestamptz 同等です(私は後者を好みます)。したがって、記事と同じ構文を使用するために、次のように書き直します。

    db=# SELECT '2012-03-05 17:00:00+0'::timestamptz;
          timestamptz
    ------------------------
     2012-03-05 17:00:00+00
    

    さて、ここで何が起こっているのですか?まあ、あなたの元の説明よりも少ないです。文字列は単純にtimestamptzとして解析されます 。結果が出力されると、現在設定されているtimezoneが使用されます。 基になるデータ構造の人間が読める表現に変換するように構成します。つまり、2012-03-05 17:00:00+00

    timezoneを変更しましょう 設定して何が起こるかを確認します:

    db=# SET timezone TO 'Europe/Berlin';
    SET
    db=# SELECT '2012-03-05 17:00:00+0'::timestamptz;
          timestamptz
    ------------------------
     2012-03-05 18:00:00+01
    

    変更されたのは方法だけです timestamptz 画面に印刷されます。つまり、ヨーロッパ/ベルリンを使用します。 タイムゾーン。

    例2

    db=# SELECT timestamptz '2012-03-05 18:00:00+1';
          timestamptz
    ------------------------
     2012-03-05 17:00:00+00
    (1 row)
    

    繰り返しますが、日付を解析するだけです。

    例3

    db=# SELECT timestamp '2012-03-05 18:00:00+1';
          timestamp
    ---------------------
     2012-03-05 18:00:00
    (1 row)
    

    これは、'2012-03-05 18:00:00+1'::timestampと同じです。 。ここで何が起こるかというと、timestampを要求しているため、タイムゾーンオフセットは単に無視されます。 。

    例4

    db=# SELECT timestamp '2012-03-05 11:00:00' AT TIME ZONE '+6';
            timezone
    ------------------------
     2012-03-05 17:00:00+00
    (1 row)
    

    簡単に書き直してみましょう:

    db=# SELECT timezone('+6', '2012-03-05 11:00:00'::timestamp);
            timezone
    ------------------------
     2012-03-05 17:00:00+00
    (1 row)
    

    これは質問です:+6時間のオフセットがあるタイムゾーンの壁の時計が2012-03-05 11:00:00を示していた絶対時間は何でしたか ?

    例5

    db=# SELECT timestamp '2012-03-05 17:00:00' AT TIME ZONE 'UTC';
            timezone
    ------------------------
     2012-03-05 17:00:00+00
    (1 row)
    

    書き直してみましょう:

    db=# SELECT timezone('UTC', '2012-03-05 17:00:00'::timestamp);
            timezone
    ------------------------
     2012-03-05 17:00:00+00
    (1 row)
    

    これは質問です:タイムゾーンUTCの壁の時計が2012-03-05 17:00:00を示していた絶対時間は何でしたか ?

    例6

    db=# SELECT timestamp '2012-03-05 17:00:00'::timestamp;
          timestamp
    ---------------------
     2012-03-05 17:00:00
    (1 row)
    

    ここでは、timestampに2回キャストしています 、違いはありません。簡単にしましょう:

    db=# SELECT '2012-03-05 17:00:00'::timestamp;
          timestamp
    ---------------------
     2012-03-05 17:00:00
    (1 row)
    

    それは明らかだと思います。

    例7

    db=# SELECT timestamp '2012-03-05 17:00:00'::timestamptz;
          timestamptz
    ------------------------
     2012-03-05 17:00:00+00
    (1 row)
    

    書き直してみましょう:

    db=# SELECT ('2012-03-05 17:00:00'::timestamp)::timestamptz;
          timestamptz
    ------------------------
     2012-03-05 17:00:00+00
    (1 row)
    

    最初に文字列をtimestampとして解析します そしてそれをtimestamptzに変換します 現在設定されているtimezoneを使用する 。 timezoneを変更した場合 、Postgresはtimestampを変換するときにそのタイムゾーンを想定しているため、別のものが得られます (またはタイムゾーン情報が不足している文字列)からtimestamptz

    db=# SET timezone TO 'Europe/Berlin';
    SET
    db=# SELECT ('2012-03-05 17:00:00'::timestamp)::timestamptz;
          timestamptz
    ------------------------
     2012-03-05 17:00:00+01
    (1 row)
    

    UTCで表されるこの絶対時間は、2012-03-05 16:00:00+00です。 、したがって、元の例とは異なります。

    これが物事を明らかにすることを願っています。繰り返しますが、timestampの違いを理解する およびtimestamptz キーです。実時間と絶対時間の違いを考えてください。



    1. SQLLIKEクエリの失敗-プリペアドステートメントの致命的なエラー

    2. テキストフィールドを更新するときにpostgresqlに改行を挿入する

    3. MySqlからSQLServer2008に移行する

    4. MySQLで列を遅らせるにはどうすればよいですか?