現地時間を保存したいようです 特定のタイムゾーンに関して。その場合は、timestamp
を保存します。 (タイムゾーンなし)およびtimezone
別の列にあります。
たとえば、2030年2月26日の午前10時にシカゴで発生し、午前10時に発生するイベントを記録するとします。現地時間 その日に有効なタイムゾーンルールに関係なく。
データベースにタイムゾーンなしでタイムスタンプが保存されている場合:
unutbu=# select '2030-02-26 10:00:00'::timestamp as localtime, 'America/Chicago' AS tzone;
+---------------------+-----------------+
| localtime | tzone |
+---------------------+-----------------+
| 2030-02-26 10:00:00 | America/Chicago |
+---------------------+-----------------+
その後、
を使用してイベントのUTC日時を見つけることができますunutbu=# select '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
| timezone |
+---------------------+
| 2030-02-26 16:00:00 |
+---------------------+
クエリはUTC日時、2030-02-26 16:00:00
を返します 、これは2030-02-26 10:00:00
に対応します シカゴの現地時間。
AT TIME ZONE
の使用 タイムゾーンルールの適用を遅らせる timestamptz
の代わりに、クエリが実行されたとき 挿入されました。
AT TIME ZONE
の使用 timestamp
日時を指定されたタイムゾーンにローカライズしますが、レポート ユーザーのタイムゾーンの日時 。AT TIME ZONE
の使用 timestamptz
で 日時を指定されたタイムゾーンに変換してからオフセットを削除し、timestamp
を返します。 。上記、AT TIME ZONE
2回使用されます。最初はtimestamp
をローカライズするためです 次に、返されたtimestamptz
を変換します 新しいタイムゾーン(UTC)に。結果はtimestamp
です UTCで。
これは、AT TIME ZONE
を示す例です。 timestamp
でのの動作 s:
unutbu=# SET timezone = 'America/Chicago';
unutbu=# SELECT '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago';
+------------------------+
| timezone |
+------------------------+
| 2030-02-26 10:00:00-06 |
+------------------------+
unutbu=# SET timezone = 'America/Los_Angeles';
unutbu=# SELECT '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago';
+------------------------+
| timezone |
+------------------------+
| 2030-02-26 08:00:00-08 |
+------------------------+
2030-02-26 10:00:00-06
および2030-02-26 08:00:00-08
日時は同じですが、異なるユーザータイムゾーンで報告されます。これは、シカゴの午前10時がロサンゼルスの午前8時であることを示しています(現在のタイムゾーン定義を使用):
unutbu=# SELECT '2030-02-26 10:00:00-06'::timestamptz AT TIME ZONE 'America/Los_Angeles';
+---------------------+
| timezone |
+---------------------+
| 2030-02-26 08:00:00 |
+---------------------+
AT TIME ZONE
を使用する代わりの方法 2回は、ユーザーのタイムゾーンを設定する
ことです。 UTC
へ 。次に、使用できます
select localtime AT TIME ZONE tzone
このようにすると、timestamptz
timestamp
の代わりに返されます 。
存在しない時間やあいまいな時間が存在する可能性があるため、現地時間を保存すると問題が発生する可能性があることに注意してください。たとえば、2018-03-11 02:30:00
America/Chicago
に存在しない現地時間です 。 Postgresqlは、夏時間(DST)が開始された後の対応する時刻を参照すると想定して、存在しない現地時間を正規化します(誰かが時計を進めるのを忘れたかのように):
unutbu=# select '2018-03-11 02:30:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
| timezone |
+---------------------+
| 2018-03-11 08:30:00 |
+---------------------+
(1 row)
unutbu=# select '2018-03-11 03:30:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
| timezone |
+---------------------+
| 2018-03-11 08:30:00 |
+---------------------+
(1 row)
あいまいな現地時間の例は、2018-11-04 01:00:00
です。 America/Chicago
。 DSTが原因で2回発生します。 Postgresqlは、DSTが終了した後、後で選択することでこのあいまいさを解決します。
unutbu=# select '2018-11-04 01:00:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
| timezone |
+---------------------+
| 2018-11-04 07:00:00 |
+---------------------+
これは、2018-11-04 06:00:00 UTC
を参照する方法がないことを意味することに注意してください 現地時間をAmerica/Chicago
に保存する タイムゾーン:
unutbu=# select '2018-11-04 00:59:59'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
| timezone |
+---------------------+
| 2018-11-04 05:59:59 |
+---------------------+