HOWTO · PostgreSQL

PostgreSQL で UTC 現在時刻をデフォルトとして使用する

この記事では、PostgreSQL で UTC 現在時刻をデフォルトとして使用する方法について説明します。

このページの内容

今日、PostgreSQL では、UTC 現在時刻を PostgreSQL のテーブルのデフォルト時刻として使用する方法を学習します。 UTC は 協定世界時 の略です。

これは、世界中の時計と時刻を調整する UNIVERSAL 方式です。 ローカル タイム ゾーンには、特定の場所のみに指定された時間があり、主に庶民をよりよく理解するために使用されます。

PostgreSQL サーバーで現在の時刻を UTC に設定するさまざまなソリューションを見ていきます。

PostgreSQL で UTC 時刻を取得する標準的な方法

簡単なクエリを呼び出して、現在の PostgreSQL セッションの時間を UTC 形式で取得できます。

select now() at time zone ('utc');

これにより、次のようなテーブルが返されます。

出力:

timezone (timestamp without timezone)
"2022-04-27 16:38:29.354155"

では、これはどのように機能するのでしょうか。 まず、NOW() を呼び出して、現在のトランザクションの開始時刻を取得します。

これは、UTC 形式で定義された TIME ZONE から取得されます。 したがって、この単純なクエリは、必要なゾーンの現在の時刻を取得するのに役立ちます。

TIMEZONE 句を定義せずにこのクエリを呼び出す傾向がある場合、セッションが次のように GMT で指定された時間値を返すことに気付くでしょう。

select now();

出力:

timezone (timestamp with timezone)
2022-04-27 21:55:14.098115+05

したがって、TIME 値を取得するときは UTC を指定することが不可欠です。 多くの場合、TIMESTAMP を使用している間、システムの TIME 値は UTC で保存されますが、それ以外の場合は別の方法で指定されます。

また、ローカル日付から UTC 日付へ、またはその逆の暗黙的な変換が行われる場合もあります。

UTC 形式の TIMESTAMP 列を含むテーブルを作成する

レコード情報に有効な時間が含まれている必要があるテーブルにデータを INSERTING する一般的な方法は、自動時刻ハンドラーを追加することです。これは、更新された現在の DATE TIME で構成される列であり、レコードが INSERTED になるとそれを保存します。 .

UTC のエイリアスである TIMESTAMP WITHOUT TIME ZONE を使用して、INSERTION で UTC 値を含む列を指定できます。 これを行うには、次のようにクエリを書きましょう。

create temporary table DELFTSTACK_TUT(time_stamp timestamp without time zone default (now() at time zone('utc')), rec int);

上記のクエリを実行すると、DEFAULT TIMESTAMP 列を含む一時テーブルが作成されます。 上記のテーブルで INSERT を呼び出すと、挿入されたすべてのレコードには、UTC で生成されて追加された自動 TIMESTAMP が含まれます。

次のようにクエリを実行します。

insert into DELFTSTACK_TUT (rec) VALUES(1), (2), (3);

出力で次のようなテーブルが返されます。

timestamp without time zone    rec
"2022-04-27 17:13:31.159356"	1
"2022-04-27 17:13:31.159356"	2
"2022-04-27 17:13:31.159356"	3

したがって、NOW() 式を UTC とともに DEFAULT 句で使用すると、記録保持が必要なテーブルを作成するのに最適であることがわかります。

DEFAULT 句を囲む括弧を見逃さないようにしてください。これは、式全体を 1つの項目として取り込んでから、それを使用してそれぞれのレコードに値を入力する必要があるためです。

異なるバージョンの PostgreSQL では、異なる問題が発生する可能性があります。 TIME ZONE の定義でエラーが発生する場合があります。

utc ではなく UTC を記述すると、異なる CASE が原因で問題が発生する可能性があります。 したがって、PostgreSQL でこのような式を記述する際には、CASE SENSITIVE EXPRESSIONS と CONSTRAINTS に注意することが重要です。

TIMEZONE() を使用して、PostgreSQL のテーブル列の UTC 形式で TIME を取得する

列の UTC 形式で TIME DATE の値を取得するもう 1つの簡単な方法は、クエリを呼び出すことです。

create temporary table DELFTSTACK_TUT(time_stamp timestamp without time zone default ('utc', now()), rec int);

しかし、これはCREATING時に以下のようにエラーを返します。

出力:

ERROR:  column "time_stamp" is of type timestamp without time zone but default expression is of type record
HINT:  You will need to rewrite or cast the expression.
SQL state: 42804

タイプの不一致が原因でエラーが発生します。 CAST または上記の式を書き直して、このエラーを取り除くことができます。

ただし、理解を深めるために、クエリを 2つの異なる方法で CAST します。 以下の最初のものは、この TIMESTAMP を UTC パラメータで提供される別の TIMEZONE に変換します。

create temporary table DELFTSTACK_TUT(time_stamp timestamp without time zone default timezone('utc', now()), rec int);

これにより、次のような表が得られます。

出力:

timestamp without time zone    rec
"2022-04-27 17:45:34.257072"	1
"2022-04-27 17:45:34.257072"	2
"2022-04-27 17:45:34.257072"	3

2 番目の回避策である CASTS では、この式を TEXT に変換し、PostgreSQL のバージョンによって違いがある場合に備えて、出力を取得します。

create temporary table DELFTSTACK_TUT(time_stamp  timestamp without time zone default now()::timestamp, rec int);

上記のレコードを実行してから INSERTING 3 レコードをテーブルに実行すると、次のような出力が得られます。

timestamp without time zone    rec
"2022-04-27 22:49:51.654846"	1
"2022-04-27 22:49:51.654846"	2
"2022-04-27 22:49:51.654846"	3

したがって、NOW() を TIMESTAMP にキャストし、それを UTC 指定の列に挿入すると、正しい結果が得られることがわかります。 ただし、この後者のソリューションは UTC オフセットを考慮せず、単純なタイムスタンプのみを記録として保持します。

UTC ではなく INTERVAL -8:00 を使用

セッションで UTC を記述するという CASE 問題に行き詰まりたくない場合は、次のようにクエリを記述できます。

create temporary table DELFTSTACK_TUT(time_stamp timestamp without time zone default timezone(INTERVAL '+00:00', now()), rec int);

このクエリを実行してテーブルを作成し、INSERT を呼び出すと、正しい結果が UTC 形式で返されます。 +00:00 を持つ INTERVAL は、PostgreSQL のドキュメントでは、+00.00 のオフセットを持つ UTC または ZULU (軍事略語) タイム ゾーンに属するものとして定義されています。

結果は次のように生成されます。

 timestamp without time zone   rec
"2022-04-27 17:57:36.054746"	1
"2022-04-27 17:57:36.054746"	2
"2022-04-27 17:57:36.054746"	3

UTC 時間形式を関数にラップして効率を高める

UTC で現在時刻を取得する単純な関数を作成し、それをレコード INSERTIONS で使用できます。

create function get_UTC_time()
returns timestamp as
$$
  select now() at time zone 'utc';
$$
language sql;

次に、SELECT クエリを呼び出して、次のように現在の時刻を取得します。

select * from get_UTC_time();

これにより、次の結果が出力されます。

timestamp without time zone
"2022-04-27 18:01:35.42119"

また、これをテーブル内で次のように使用できます。

create temporary table DELFTSTACK_TUT(time_stamp  timestamp without time zone default get_UTC_time());

したがって、PostgreSQL セッションの時間を UTC 形式で取得するさまざまな方法を調べました。 PostgreSQL のインストールまたはバージョンに従って、これらを必ず変更してください。

ただし、各クエリとその条件と制約を可能な限り詳細にカバーするために、レベルで最善を尽くします。