Jak uzyskać kolumnę znacznika czasu w PostgreSQL w milisekundach?

29

Mam kolumnę „utworzono” z typem timestamp without time zone default now()w bazie danych PostgreSQL.

Jeśli wybiorę kolumny, domyślnie ma ładny i czytelny format:

SELECT created FROM mytable;

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

Ale chciałbym uzyskać znacznik czasu tylko w milisekundach (jako długi). Coś takiego:

WYBIERZ mój format (utworzony) z mytable;

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

Jak mogę uzyskać kolumnę znacznika czasu w PostgreSQL w milisekundach?


Odpowiedź do Jacka:

Dostaję taką samą różnicę jak ty (-3600), ale jeśli używam timestamp with time zone, widzę, że „błąd” lub różnica wynika z tego, że „1970-01-01” dostaje strefę czasową +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)

Czy różnica jest błędem? Mogę być z powodu „czasu letniego” w tej chwili?


Interesujące również podczas to_timestamp()wstawiania znacznika czasu 0 i 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
źródło

Odpowiedzi:

35

Użyj EXTRACTi znacznika czasu UNIX

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

dałbym

1305621628876.94

Pomnóż go, 1000aby zamienić go w milisekundy. Następnie możesz przekonwertować go na dowolne ( dziesiętne byłoby dobrym wyborem). Nie zapomnij pamiętać o strefie czasowej. JackPDouglas ma taki przykład w swojej odpowiedzi . Oto fragment jego odpowiedzi ( createdbędący kolumną z twoim terminarzem), który ilustruje, jak pracować ze strefami czasowymi:

SELECT EXTRACT(EPOCH FROM created AT TIME ZONE 'UTC') FROM my_table;
DrColossos
źródło
5

--EDYTOWAĆ--

Odkryłem, że to (patrz poniżej) jest zasadniczo błędne. Zobacz Jak uzyskać bieżący znacznik czasu unix z PostgreSQL? za źródło mojego zamieszania ...

--END EDIT--

Publikowanie jako odpowiedź, ponieważ nie będzie działać jako komentarz.

testbed:

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 |

zapytania:

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

Uwaga date_partw trzecim zapytaniu jest: 130563 83 28.03266 - 3600 różnych.

Jack Douglas
źródło