基本的にあなたが望むものは次のとおりです。
$ select starts_at AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific' from schedules where id = 40
私はこの記事から解決策を得ました、それはまっすぐな金です!!! この重要な問題を非常に明確に説明しています。pstgrsqlTZ管理をよりよく理解したい場合は、読んでください。
現地時間でゾーンなしでPostgreSQLタイムスタンプを表現する
これが起こっていることです。まず、PSTタイムゾーンがUTCタイムゾーンより8時間遅れていることを知っておく必要があります。たとえば、2014年1月1日午後4時30分PST(2014年1月1日水曜日16:00:30 -0800)は、2014年1月2日00:30に相当します。協定世界時(2014年1月2日木曜日00:00:30 +0000)。PSTの午後4時以降はいつでも、UTCとして解釈されて翌日にスリップします。
また、前述のErwin Brandstetterのように、postresqlには2種類のタイムスタンプデータ型があります。1つはタイムゾーンあり、もう1つはタイムゾーンなしです。タイムスタンプにタイムゾーンが含まれている場合は、次のようにします。
$ select starts_at AT TIME ZONE 'US/Pacific' from schedules where id = 40
動作します。ただし、タイムスタンプがタイムゾーンなしの場合、上記のコマンドの実行は機能しません。最初にタイムゾーンなしのタイムスタンプをタイムゾーン付きのタイムスタンプ、つまりUTCタイムゾーンに変換してから、目的の「PST」または「US/」に変換する必要があります。パシフィック」(これは、夏時間の問題までは同じです。どちらでも問題ないと思います)。
タイムゾーンのないタイムスタンプを作成する例を示してみましょう。便宜上、ローカルタイムゾーンが実際に「PST」であると仮定しましょう(そうでない場合は、少し複雑になりますが、この説明では不要です)。
私が持っていると言う:
$ select timestamp '2014-01-2 00:30:00' AS a, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AS b, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AT TIME ZONE 'PST' AS c, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d
これにより、次のようになります。
"a"=>"2014-01-02 00:30:00" (This is the timezoneless timestamp)
"b"=>"2014-01-02 00:30:00+00" (This is the UTC TZ timestamp, note that up to a timezone, it is equivalent to the timezoneless one)
"c"=>"2014-01-01 16:30:00" (This is the correct 'PST' TZ conversion of the UTC timezone, if you read the documentation postgresql will not print the actual TZ for this conversion)
"d"=>"2014-01-02 08:30:00+00"
最後のタイムスタンプは、postgresqlでタイムゾーンのないタイムスタンプをUTCから「PST」に変換することに関するすべての混乱の理由です。私たちが書くとき:
timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d
タイムゾーンのないタイムスタンプを取得して、それを'PST TZに変換しようとしています(postgresqlはUTC TZからタイムスタンプを変換することを間接的に理解していると想定していますが、postresqlには独自の計画があります!)。実際には、postgresqlが行うことは、タイムゾーンのないタイムスタンプ( '2014-01-2 00:30:00)を取り、それがすでに' PST' TZタイムスタンプ(つまり、2014-01-2 00:30)であるかのように扱うことです。 :00 -0800)そしてそれをUTCタイムゾーンに変換します!!! つまり、実際には、後ろではなく8時間前にプッシュします。したがって、(2014-01-02 08:30:00 + 00)が得られます。
とにかく、この最後の(直感的でない)行動はすべての混乱の原因です。より詳細な説明が必要な場合は、記事を読んでください。実際には、この最後の部分とは少し異なる結果が得られましたが、一般的な考え方は同じです。