「+hh:mm」(または「-hh:mm」) の形式の文字列を単純に使用することを考えています。これは必要かつ十分ですか?
注: 日付や時刻を保存する必要はなく、タイムゾーンだけを保存する必要があります。
「+hh:mm」(または「-hh:mm」) の形式の文字列を単純に使用することを考えています。これは必要かつ十分ですか?
注: 日付や時刻を保存する必要はなく、タイムゾーンだけを保存する必要があります。
残念ながら、PostgreSQL はタイム ゾーン データ型を提供していないため、おそらく を使用する必要がありますtext
。
interval
一見、論理的なオプションのように見えますが、用途によっては適切です。ただし、夏時間は考慮されておらず、同じ UTC オフセット内の異なる地域に異なる DST 規則があるという事実も考慮されていません。
UTC オフセットからタイム ゾーンへの 1:1 マッピングはありません。
たとえば、Australia/Sydney
(ニュー サウス ウェールズ) のタイム ゾーンはUTC+10
( EST
)、またはサマータイム中のUTC+11
( ) です。EDT
はい、それEST
は米国が使用するのと同じ頭字語です。タイム ゾーンの頭字語は、tzdata データベース内で一意ではないため、Pg にtimezone_abbreviations
設定があります。さらに悪いことに、ブリスベン (クイーンズランド州) はほぼ同じ経度にあり、UTC+10 EST
... に入っていますが、サマータイムがないため、-1
NSW の DST 中にニューサウスウェールズとずれることがあります。
(更新: 最近ではオーストラリアがA
接頭辞を採用したためAEST
、東部の州として TZ の頭字語を使用していますがEST
、WST
一般的に使用されています)。
かなり混乱しますか?
保存する必要があるのがUTC オフセットだけの場合は、interval
が適切です。タイム ゾーンを保存する場合は、 として保存しtext
ます。現時点では検証してタイム ゾーン オフセットに変換するのは面倒ですが、少なくとも DST には対応しています。
理想的な世界では、一連の既知のタイムゾーンへの外部キーを持つことができます。ビューとドメインを使用すると、これに近いことができます。
David E. Wheleer によるこのwiki ヒントは、タイムゾーンとしての有効性がテストされたドメインを作成します。
CREATE OR REPLACE FUNCTION is_timezone( tz TEXT ) RETURNS BOOLEAN as $$
BEGIN
PERFORM now() AT TIME ZONE tz;
RETURN TRUE;
EXCEPTION WHEN invalid_parameter_value THEN
RETURN FALSE;
END;
$$ language plpgsql STABLE;
CREATE DOMAIN timezone AS CITEXT
CHECK ( is_timezone( value ) );
既知のタイムゾーンのリストがあると便利です。この場合、ドメインを省略して、(ビューから取得したpg_timezone_names
)既知のタイムゾーン名を含む 1 つのテーブルに制約を適用するだけで、ドメインを別の場所に公開する必要がなくなります。
CREATE TABLE tzone
(
tzone_name text PRIMARY KEY (tzone_name) CHECK (is_timezone(tzone_name))
);
INSERT INTO tzone (tzone_name)
SELECT name FROM pg_timezone_names;
次に、外部キーを使用して正確さを強制できます。
CREATE TABLE myTable (
...
tzone TEXT REFERENCES tzone(tzone_name)
);
「+hh:mm」と「-hh:mm」はタイムゾーンではなく、UTCオフセットです。それらを保存するのに適した形式は、分単位のオフセットを持つ符号付き整数です。次のようなものも使用できますinterval
が、クエリなどのようにPostgreSQLで直接日付計算を実行する場合にのみ役立ちます。通常、これらの計算は別の言語で実行しますが、サポートされている場合はその言語に依存しますinterval
タイプがよく、日付/時刻ライブラリが適切かどうか。しかし、整数をある種のinterval
ような型に変換することは、Pythonのtimedelta
ように簡単なはずなので、個人的には整数として格納するだけです。
タイムゾーンには名前があり、タイムゾーンの標準化された名前はありませんが、「tz」または「zoneinfo」データベースには事実上の標準が1つあり、「Europe / Paris」、「Americas / New_York」、「米国/太平洋」。それらは文字列として保存する必要があります。
Windowsは、「ロマンスタイム」など、まったく異なる名前を使用します(尋ねないでください)。文字列と同様にそれらを保存することができますが、私はそれを避けます。これらの名前はWindowsの外部では使用されず、名前は意味がありません。さらに、Windowsの翻訳バージョンは、これらのタイムゾーンに翻訳された名前を使用する傾向があり、さらに悪化します。
「PDT」や「EST」などの略語は、一意ではないため、タイムゾーン名として使用できません。すべて「CST」と呼ばれる4つの異なるタイムゾーンがあるので(私は思うか、それとも5つでしたか?)、それは使用できません。
つまり、タイムゾーンの場合、名前を文字列として保存します。UTCオフセットの場合、オフセットを分単位で符号付き整数として格納します。
多分間隔
postgres=# select interval '01:30'; 間隔 ---------- 01:30:00 (1行) postgres=# select interval '-01:30'; 間隔 ----------- -01:30:00 (1行)