Как получить столбец отметки времени в PostgreSQL всего за миллисекунды?

29

У меня есть столбец «создан» с типом timestamp without time zone default now()в базе данных PostgreSQL.

Если я выберу столбцы, по умолчанию у них будет хороший и читаемый формат:

SELECT created FROM mytable;

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

Но я бы хотел получить отметку времени всего за миллисекунды (как Long). Что-то вроде этого:

ВЫБЕРИТЕ myformat (создано) ИЗ mytable;

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

Как получить столбец отметки времени в PostgreSQL всего за миллисекунды?


Ответ Джеку:

Я получаю ту же разницу, что и вы (-3600), но если я использую, timestamp with time zoneя вижу, что «ошибка» или разница в том, что «1970-01-01» получает часовой пояс +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)

Является ли разница ошибкой? Может быть, из-за "летнего времени" на данный момент?


Также интересно использовать to_timestamp()при вставке отметки времени 0 и 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
источник

Ответы:

35

Используйте EXTRACTи UNIX-Timestamp

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

даст

+1305621628876,94

Умножьте это на, 1000чтобы превратить это в миллисекунды. Затем вы можете преобразовать его в то, что вы хотите ( десятичный будет хорошим выбором). Не забывайте помнить о часовом поясе. У ДжекПугласа есть такой пример в его ответе . Вот выдержка из его ответа ( createdявляющегося столбцом с вашей временной меткой), который иллюстрирует, как работать с часовыми поясами:

SELECT EXTRACT(EPOCH FROM created AT TIME ZONE 'UTC') FROM my_table;
DrColossos
источник
5

--РЕДАКТИРОВАТЬ--

Я обнаружил, что это (см. Ниже) в основном неправильно. См. Как мне получить текущую метку времени Unix из PostgreSQL? для источника моего замешательства ...

--END EDIT--

Публиковать как ответ, потому что это не будет работать как комментарий.

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 |

запросы:

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

примечание date_partв третьем запросе: 130563 83 28.03266 - 3600 разных.

Джек Дуглас
источник