NIXタイムスタンプ は、1970年1月1日のUTC午前0時からの秒数です。
PostgreSQLから正しいUNIXタイムスタンプを取得するにはどうすればよいですか?
currenttimestamp.com および timestamp.1e5b.de と比較すると、PostgreSQLから予想時間を取得できません。
これは正しいタイムスタンプを返します:
SELECT extract(Epoch from now());
これはそうではありませんが:
SELECT extract(Epoch from now() at time zone 'utc');
私はタイムゾーンUTC +02に住んでいます。 PostgreSQLから現在のUNIXタイムスタンプを取得する正しい方法は何ですか?
これは正しい時間とタイムゾーンを返します:
SELECT now();
now
-------------------------------
2011-05-18 10:34:10.820464+02
別の比較:
select now(),
extract(Epoch from now()),
extract(Epoch from now() at time zone 'utc');
now | date_part | date_part
-------------------------------+------------------+------------------
2011-05-18 10:38:16.439332+02 | 1305707896.43933 | 1305700696.43933
(1 row)
Unix timestamp from the web sites:
1305707967
Postgresでは、_timestamp with time zone
_はtimestamptz
、_timestamp without time zone
_はtimestamp
と省略できます。簡単にするために、短い型名を使用します。
あなたが言うように、postgres timestamptz
のようなUnixタイムスタンプをnow()
から取得するのは簡単です:
_select extract(Epoch from now());
_
now()
を含む、timestamptz
型の絶対時刻を取得するために知っておく必要があるのは、これだけです。
timestamp
フィールドがある場合にのみ、状況は複雑になります。
now()
のようなtimestamptz
データをそのフィールドに入れると、最初に特定のタイムゾーンに変換されます(明示的に_at time zone
_で、またはセッションのタイムゾーンに変換することにより)。タイムゾーン情報は破棄されます。それはもはや絶対時間を参照しません。そのため、通常はタイムスタンプをtimestamp
として保存する必要はなく、通常はtimestamptz
を使用します。特定の日付の午後6時にフィルムがリリースされる可能性がありますすべてのタイムゾーンで、それは一種のユースケースです。
単一のタイムゾーンでのみ作業する場合は、timestamp
を(誤)使用することで回避できる可能性があります。 timestamptz
への変換は、DSTに対処するのに十分なほど賢く、タイムスタンプは、変換のために現在のタイムゾーンであると想定されます。以下はGMT/BSTの例です。
_select '2011-03-27 00:59:00.0+00'::timestamptz::timestamp::timestamptz
, '2011-03-27 01:00:00.0+00'::timestamptz::timestamp::timestamptz;
/*
|timestamptz |timestamptz |
|:---------------------|:---------------------|
|2011-03-27 00:59:00+00|2011-03-27 02:00:00+01|
*/
_
ただし、次の紛らわしい動作に注意してください。
_set timezone to 0;
values(1, '1970-01-01 00:00:00+00'::timestamp::timestamptz)
, (2, '1970-01-01 00:00:00+02'::timestamp::timestamptz);
/*
|column1|column2 |
|------:|:---------------------|
| 1|1970-01-01 00:00:00+00|
| 2|1970-01-01 00:00:00+00|
*/
_
これ 理由 :
PostgreSQLはリテラル文字列のタイプを判別する前にその内容を検査することはないため、両方の[…]をタイムゾーンなしのタイムスタンプとして扱います。リテラルがタイムゾーン付きのタイムスタンプとして扱われるようにするには、正しい明示的なタイプを指定します。タイムゾーンなしのタイムスタンプであると判断されたリテラルでは、PostgreSQLはタイムゾーンの指示を黙って無視します。
SELECT extract(Epoch from now() at time zone 'utc');
postgresタイムゾーン変換は結果からタイムゾーン情報を破棄するため、正しいタイムスタンプを返しません:
9.9.3。 ATタイムゾーン
構文:タイムゾーンなしのタイムスタンプAT TIME ZONE zone
戻り値:タイムゾーン付きのタイムスタンプ
指定されたタイムゾーンにあるタイムゾーンなしのタイムスタンプを扱います構文:タイムゾーン付きのタイムスタンプAT TIME ZONE zone
戻り値:タイムゾーンなしのタイムスタンプ
タイムゾーンを指定せずに、タイムゾーンを含む指定されたタイムスタンプを新しいタイムゾーンに変換します
その後、extractはタイムゾーンなしのタイムスタンプを調べ、それを現地時間と見なします(実際にはすでにutcですが)。
正しい方法は次のとおりです。
select now(),
extract(Epoch from now()), -- correct
extract(Epoch from now() at time zone 'utc'), -- incorrect
extract(Epoch from now() at time zone 'utc' at time zone 'utc'); -- correct
now | date_part | date_part | date_part
-------------------------------+------------------+------------------+------------------
2014-10-14 10:19:23.726908+02 | 1413274763.72691 | 1413267563.72691 | 1413274763.72691
(1 row)
最後の行で最初のat time zone
は変換を実行し、2番目は結果に新しいタイムゾーンを割り当てます。