2

IT の 2 つの惨劇のうちの 1 つは、タイムスタンプとタイム ゾーン (もう 1 つは文字エンコーディング) であり、何度も何度も遭遇し続けます...

その点で、私は現在、PostgreSQL データベースに格納する Java アプリケーション内のさまざまなタイムスタンプに関連する問題を抱えています。

簡単にするために、次の表があると仮定します。

CREATE TABLE ts_test
(
  id integer NOT NULL,
  utc timestamp without time zone,
  local timestamp with time zone,
  CONSTRAINT pk PRIMARY KEY (id)
)

そのため、UTC タイム スタンプとローカル タイム スタンプを保存する必要があります。私の場合は中央ヨーロッパの夏時間なので、現在は UTC+2 です。

さらに、テーブルに 2 つのエントリがあると仮定すると、psql コンソールに次のように出力されます (データベースは UTC で実行されます)。

# select id,  utc, local, local-utc as diff from ts_test;
 id |         utc         |         local          |   diff   
----+---------------------+------------------------+----------
  1 | 2012-06-27 12:00:00 | 2012-06-27 12:00:00+00 | 00:00:00
  2 | 2012-06-27 12:00:00 | 2012-06-27 14:00:00+00 | 02:00:00
(2 rows)

ここで、いくつかの疑問が生じます。

  • ローカル列の出力は正確には何を意味していますか?
  • システムはタイムゾーンをどのように認識しますか?値を挿入しましたか?
  • 保存されている実際の生の値 (ミリ秒など) を確認するにはどうすればよいですか?

最初の行のローカルの「12:00:00+00」は、UTC では 12:00、CEST では 14:00 であることを意味していると思います。しかし、2 行目のローカルの "14:00:00+00" は、CEST 14:00 の正しい値であると思われます (これは 2 時間の差分でサポートされています)。

しかし、SQL挿入を介して2行目を生成するには、次のように書く必要があります

insert into ts_test (id, utc, local) values (2, '2012-06-27 12:00:00', '2012-06-27 16:00:00+02');

これもまた、述語をサポートしません。

この長い質問を要約すると、この全体がどのように詳細に機能するか、出力が何を意味するのか、ローカルタイムスタンプをデータベースに正しく書き込む方法について誰か教えてもらえますか?

4

1 に答える 1

1

local列の出力によると、 SQL セッションのタイム ゾーンは、居住地のタイム ゾーンに設定されているUTCGMT、設定されていません。おそらくこれは、データベースが UTC で実行されるという意味です。これが問題の根本ですが、詳しく説明してみましょう。

データ リポジトリとしてのデータベース自体にはタイムゾーンがありませんが、各 SQL セッションには独自のタイムゾーンがあります。

SQL セッションによって要求された場合、 の値はtimestamp without time zoneセッションのタイム ゾーンにローテーションされず、タイム オフセットも表示されませんが、 の値timestamp with time zoneセッションのタイム ゾーンにローテーションされ、このタイム ゾーンのタイム オフセットが表示されます。それが両者の違いです。

値を読み取るときに重要なのは、この値を要求している SQL セッションのタイム ゾーンだけであるため、タイム ゾーンはどのデータ型にも格納されません。

SQL タイム ゾーンを に設定するUTCことは、質問の他の部分と矛盾するため、お勧めできません。

そのため、UTC タイム スタンプとローカル タイム スタンプを保存する必要があります。私の場合は中央ヨーロッパの夏時間なので、現在は UTC+2 です。

SQL セッションにリアルタイム ゾーンを知らせると、意図したとおりに機能し始めます。そうしないと、timestamp with time zone本質的に役に立たない。

utc timestamp without time zoneまた、同じ時刻をandに格納してもlocal timestamp with time zone意味がないことに注意してくださいutc

SELECT local AT TIME ZONE 'UTC' FROM ts_test WHERE...

編集:コメント内の質問への回答:

Q: セッションでタイムゾーンが現地時間に設定されている場合、たとえば ...12:00:00 の utc 値に対してローカルで ...14:00:00+02 が表示されるはずだということです。

はい。

Q: アプリケーションから local フィールドに何かを書き込む場合、どのタイムゾーンが設定されているかが問題になりますか?

丁度。

Q: JDBS セッションでこれを設定するにはどうすればよいですか?

JDBCはわかりませんが、SQLレベルでは、たとえば次のようになります。

 SET timezone='Europe/Berlin';

通常は環境から自動的に設定されますが、 を含むさまざまなレベルで強制できますpostgresql.conf。セッションで明示的に設定すると、他のすべてが上書きされます。

Q: タイムスタンプの生の値をどうにかして見ることはできますか?表示時の表現の問題ではないことを確認できますか

下位レベルで動作するpageinspectを除いて、その方法はわかりません。

于 2013-06-27T12:44:01.807 に答える