Wie erhalte ich die Timestamp-Spalte in nur Millisekunden von PostgreSQL?

29

Ich habe eine Spalte "erstellt" mit Typ timestamp without time zone default now()in einer PostgreSQL-Datenbank.

Wenn ich Spalten auswähle, hat es standardmäßig ein schönes und lesbares Format:

SELECT created FROM mytable;

         created
---------------------------
2011-05-17 10:40:28.876944

Aber ich möchte den Zeitstempel in nur Millisekunden (als Long) erhalten. Etwas wie das:

SELECT myformat (erstellt) FROM mytable;

     created
-----------------
2432432343876944

Wie kann ich die Timestamp-Spalte in nur Millisekunden von PostgreSQL erhalten?


Antwort an Jack:

Ich erhalte den gleichen Unterschied wie Sie (-3600), aber wenn ich verwende, timestamp with time zonekann ich sehen, dass der "Fehler" oder Unterschied darin besteht, dass "1970-01-01" die Zeitzone erhält +01.

create table my_table_2(created timestamp with time zone);
CREATE TABLE
insert into my_table_2 (created) values (now()), ('1970-01-01');
INSERT 0 2
select created, extract(epoch from created) from my_table_2;
            created            |    date_part
-------------------------------+------------------
 2011-05-18 11:03:16.909338+02 | 1305709396.90934
 1970-01-01 00:00:00+01        |            -3600
(2 rows)

Ist der Unterschied ein Fehler? Ich kann im Moment wegen "Sommerzeit" sein?


Interessant auch beim to_timestamp()Einfügen der Zeitstempel 0 und 1.

insert into my_table_2 (created) values (to_timestamp(0));
INSERT 0 1

insert into my_table_2 (created) values (to_timestamp(1));
INSERT 0 1
select created, extract(epoch from created) from my_table_2;
            created            |    date_part
-------------------------------+------------------
 2011-05-18 11:03:16.909338+02 | 1305709396.90934
 1970-01-01 00:00:00+01        |            -3600
 1970-01-01 01:00:00+01        |                0
 1970-01-01 01:00:01+01        |                1
Jonas
quelle

Antworten:

35

Verwenden Sie EXTRACTund den UNIX-Timestamp

SELECT EXTRACT(EPOCH FROM TIMESTAMP '2011-05-17 10:40:28.876944') * 1000;

Würde geben

1305621628876.94

Multiplizieren Sie es mit 1000, um es in Millisekunden umzuwandeln. Sie können es dann konvertieren, was Sie wollen ( Dezimal wäre eine gute Wahl). Vergessen Sie nicht, die Zeitzone im Auge zu behalten. JackPDouglas hat ein solches Beispiel in seiner Antwort . Hier ist ein Auszug aus seiner Antwort ( createddie Spalte mit Ihrem Zeitstempel), die zeigt, wie man mit Zeitzonen arbeitet:

SELECT EXTRACT(EPOCH FROM created AT TIME ZONE 'UTC') FROM my_table;
DrColossos
quelle
5

--BEARBEITEN--

Ich habe festgestellt, dass dies (siehe unten) grundsätzlich falsch ist. Siehe Wie erhalte ich den aktuellen Unix-Zeitstempel von PostgreSQL? für die Quelle meiner Verwirrung ...

--END EDIT--

Als Antwort posten, da dies nicht als Kommentar funktioniert.

Prüfstand:

create role stack;
grant stack to dba;
create schema authorization stack;
set role stack;

create table my_table(created timestamp);
insert into my_table(created) values(now()),('1970-01-01');
\d my_table
              Table "stack.my_table"
 Column  |            Type             | Modifiers
---------+-----------------------------+-----------
 created | timestamp without time zone |

Fragen:

select created, extract(epoch from created) from my_table;

          created          |    date_part
---------------------------+------------------
 2011-05-17 13:18:48.03266 | 1305634728.03266
 1970-01-01 00:00:00       |            -3600


select created, extract(epoch from date_trunc('milliseconds', created)) 
from my_table;

          created          |    date_part
---------------------------+------------------
 2011-05-17 13:18:48.03266 | 1305634728.03266
 1970-01-01 00:00:00       |            -3600


select created, extract(epoch from created at time zone 'UTC') from my_table;

          created          |    date_part
---------------------------+------------------
 2011-05-17 13:18:48.03266 | 1305638328.03266
 1970-01-01 00:00:00       |                0

Hinweis date_partin der dritten Abfrage ist: 130563 83 28.03266 - 3600 anders.

Jack Douglas
quelle