it-swarm.com.de

Wie erhalte ich den aktuellen Unix-Zeitstempel von PostgreSQL?

nix-Zeitstempel ist die Anzahl der Sekunden seit Mitternacht UTC am 1. Januar 1970.

Wie erhalte ich den richtigen Unix-Zeitstempel von PostgreSQL?

Beim Vergleich mit currenttimestamp.com und timestamp.1e5b.de bekomme ich nicht die erwartete Zeit von PostgreSQL:

Dies gibt den richtigen Zeitstempel zurück:

SELECT extract(Epoch from now());

Während dies nicht:

SELECT extract(Epoch from now() at time zone 'utc');

Ich lebe in der Zeitzone UTC +02. Was ist der richtige Weg, um den aktuellen Unix-Zeitstempel von PostgreSQL zu erhalten?

Dies gibt die richtige Zeit und Zeitzone zurück:

SELECT now();
              now
-------------------------------
 2011-05-18 10:34:10.820464+02

Ein weiterer Vergleich:

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
99
Jonas

In Postgres kann timestamp with time zone Als timestamptz und timestamp without time zone Als timestamp abgekürzt werden. Ich werde die kürzeren Typnamen der Einfachheit halber verwenden.

Das Abrufen des Unix-Zeitstempels von einem Postgres timestamptz wie now() ist einfach, wie Sie sagen, nur:

select extract(Epoch from now());

Das ist wirklich alles, was Sie wissen müssen, um die absolute Zeit von irgendetwas vom Typ timestamptz zu erhalten, einschließlich now().

Die Dinge werden nur kompliziert, wenn Sie ein timestamp Feld haben.

Wenn Sie timestamptz Daten wie now() in dieses Feld einfügen, werden diese zuerst in eine bestimmte Zeitzone konvertiert (entweder explizit mit at time zone Oder durch Konvertieren in die Sitzungszeitzone) und Die Zeitzoneninformationen werden verworfen . Es bezieht sich nicht mehr auf eine absolute Zeit. Aus diesem Grund möchten Sie Zeitstempel normalerweise nicht als timestamp speichern und verwenden normalerweise timestamptz - möglicherweise wird ein Film an einem bestimmten Datum um 18 Uhr veröffentlicht In jeder Zeitzone ist dies der Anwendungsfall.

Wenn Sie immer nur in einer einzigen Zeitzone arbeiten, können Sie mit timestamp mit (mis) davonkommen. Die Konvertierung zurück nach timestamptz ist clever genug, um mit der Sommerzeit fertig zu werden, und es wird angenommen, dass sich die Zeitstempel für Konvertierungszwecke in der aktuellen Zeitzone befinden. Hier ist ein Beispiel für 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|
*/

DBFiddle

Beachten Sie jedoch das folgende verwirrende Verhalten:

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|
*/

DBFiddle

Dies liegt daran :

PostgreSQL untersucht niemals den Inhalt einer Literalzeichenfolge, bevor ihr Typ bestimmt wird, und behandelt daher beide […] als Zeitstempel ohne Zeitzone. Um sicherzustellen, dass ein Literal als Zeitstempel mit Zeitzone behandelt wird, geben Sie ihm den richtigen expliziten Typ. In einem Literal, das als Zeitstempel ohne Zeitzone festgelegt wurde, ignoriert PostgreSQL alle Zeitzonenangaben stillschweigend

SELECT extract(Epoch from now() at time zone 'utc');

gibt nicht den richtigen Zeitstempel zurück, da die Postzonen-Zeitzonenkonvertierung Zeitzoneninformationen aus dem Ergebnis entfernt:

9.9.3. AT TIME ZONE

Syntax: Zeitstempel ohne Zeitzone AT TIME ZONE Zone
Rückgabe: Zeitstempel mit Zeitzone
Behandeln Sie den angegebenen Zeitstempel ohne Zeitzone als in der angegebenen Zeitzone befindlich

Syntax: Zeitstempel mit Zeitzone AT TIME ZONE Zone
Rückgabe: Zeitstempel ohne Zeitzone
Konvertieren Sie einen bestimmten Zeitstempel mit Zeitzone in die neue Zeitzone ohne Zeitzonenbezeichnung

anschließend betrachtet Extrakt den Zeitstempel ohne Zeitzone und betrachtet ihn als Ortszeit (obwohl er tatsächlich bereits utc ist).

Der richtige Weg wäre:

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)

In der letzten Zeile das erste at time zone führt die Konvertierung durch, die zweite weist dem Ergebnis eine neue Zeitzone zu.

23
axil