powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Timestamp WO timezone
9 сообщений из 9, страница 1 из 1
Timestamp WO timezone
    #40129281
про герр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблица с одним полем:

Код: sql
1.
2.
3.
4.
5.
CREATE TABLE access_ts
(
  acces_ts timestamp without time zone NOT NULL,
  CONSTRAINT acc_ts PRIMARY KEY (acces_ts)
);


Добавляю запись в 14:02:41 по Мск
Код: sql
1.
insert into access_ts values(now()::timestamp);



отображаемое значение через PgAdmin 2022-01-25 14:02:41.157086

Получаю UTS в мс:
Код: sql
1.
2.
3.
4.
SELECT 
  (extract(epoch from "access_ts"."acces_ts"::timestamp) * 1000)::BIGINT
FROM 
  "access_ts";



получаю число: 1643119361157
что в GMT = GMT: Tuesday, 25 January 2022 г., 14:02:41.157
по Мск = вторник, 25 января 2022 г., 17:02:41.157 GMT+03:00

Почему вставка идет в локальном времени?
Как сделать, чтобы время было всегда и везде GMT?
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40129307
про герр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот такой запрос на вставку + выборку выдает 2 разных результата:


Код: sql
1.
2.
3.
4.
5.
6.
7.
INSERT INTO access_ts values(now());

SELECT (EXTRACT(EPOCH FROM now()) * 1000)::BIGINT

UNION ALL

SELECT (extract(EPOCH FROM "access_ts"."acces_ts"::timestamp) * 1000)::BIGINT FROM  "access_ts";


Результат:
1643113550846
1643124350846
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40129317
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про герр

Код: sql
1.
2.
3.
4.
5.
CREATE TABLE access_ts
(
  acces_ts timestamp without time zone NOT NULL,
  CONSTRAINT acc_ts PRIMARY KEY (acces_ts)
);


...
Почему вставка идет в локальном времени?
Как сделать, чтобы время было всегда и везде GMT?

Поменяйте тип столбца на timestamp with time zone и время всегда будет хранится в UTC, как и написано в документации:
https://postgrespro.ru/docs/postgresql/14/datatype-datetime Значения timestamp with time zone внутри всегда хранятся в UTC (Universal Coordinated Time, Всемирное скоординированное время или время по Гринвичу, GMT). Вводимое значение, в котором явно указан часовой пояс, переводится в UTC с учётом смещения данного часового пояса. Если во входной строке не указан часовой пояс, подразумевается часовой пояс, заданный системным параметром TimeZone и время так же пересчитывается в UTC со смещением timezone.

Когда значение timestamp with time zone выводится, оно всегда преобразуется из UTC в текущий часовой пояс timezone и отображается как локальное время. Чтобы получить время для другого часового пояса, нужно либо изменить timezone, либо воспользоваться конструкцией AT TIME ZONE (см. Подраздел 9.9.4).
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40129319
про герр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел Лузанов,

Код: sql
1.
2.
3.
4.
5.
CREATE TABLE public.access_ts
(
  acces_ts timestamp with time zone NOT NULL,
  CONSTRAINT acc_ts PRIMARY KEY (acces_ts)
)



Ничего не изменилось:
Вывод кода из 2-го моего поста:

автор1643115253703
1643126053703
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40129325
Ы2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про герр
вот такой запрос на вставку + выборку выдает 2 разных результата:
Код: sql
1.
2.
3.
4.
5.
6.
7.
INSERT INTO access_ts values(now());

SELECT (EXTRACT(EPOCH FROM now()) * 1000)::BIGINT

UNION ALL

SELECT (extract(EPOCH FROM "access_ts"."acces_ts"::timestamp) * 1000)::BIGINT FROM  "access_ts";


Результат:
1643113550846
1643124350846


Что вполне логично: первое значение из now(), второе — из таблицы, вставленное ранее. Заверните вставку и запрос в общую транзакцию, разница должна исчезнуть.
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40129329
про герр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ы2,

разница между этими значениями 10800000 мс, что есть 3 часа.
Запрос выполнился за 11мс.
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40129344
Ы2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про герр, now() всегда с часовым поясом, поэтому, когда вы его приводите к timestamp, вы получаете GMT микросекунд ± часовой пояс.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
INSERT INTO access_ts values(now());

SELECT (EXTRACT(EPOCH FROM now()) * 1000)::BIGINT

UNION ALL

SELECT (extract(EPOCH FROM "access_ts"."acces_ts"::timestamptz) * 1000)::BIGINT FROM  "access_ts";
INSERT 0 1
int8
---------------
1643119483688
1643119483682



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
begin ;
BEGIN
INSERT INTO access_ts values(now());
INSERT 0 1
SELECT (EXTRACT(EPOCH FROM now()) * 1000)::BIGINT
UNION ALL
SELECT (extract(EPOCH FROM "access_ts"."acces_ts"::timestamptz) * 1000)::BIGINT FROM  "access_ts";
int8
---------------
1643119721293
1643119721293
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40129492
про герр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Другая сторона вопроса:
Работаю в PG через Qt, если получаю timestamp как дата-время, то все корректно.
Если получаю как строку тогда есть сдвиг на временную зону.
Каким образом привести к одному знаменателю текстовое значение и значение даты-времени?

Т.е. поле типа timestamp without time zone в тексте значение 2022-01-26 10:00:00.001, в дата-время 1643180400001 мс, что соответствует GMT: Wednesday, 26 January 2022 г., 7:00:00.001
...
Рейтинг: 0 / 0
Timestamp WO timezone
    #40130110
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про герр
вот такой запрос на вставку + выборку выдает 2 разных результата:


Код: sql
1.
2.
3.
4.
5.
6.
7.
INSERT INTO access_ts values(now());

SELECT (EXTRACT(EPOCH FROM now()) * 1000)::BIGINT

UNION ALL

SELECT (extract(EPOCH FROM "access_ts"."acces_ts"::timestamp) * 1000)::BIGINT FROM  "access_ts";


Результат:
1643113550846
1643124350846


На самом деле всё достаточно просто... timestamp WITHOUT timezone считается не TIMESTAMP от UTC а timestamp в текущей timezone;
и смотря какую вы timezone поставите - epoch будет разный потому что ОДНО И ТОЖЕ значение timestamp without timezone значит разные моменты времени смотря от настройки timezone которая на лету меняться может.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
mboguk=# set timezone to UTC;
SET
mboguk=# SELECT (EXTRACT(EPOCH FROM now()::timestamp) * 1000)::BIGINT;
     int8      
---------------
 1643315363939
(1 row)

mboguk=# set timezone to 'Europe/Moscow';
SET
mboguk=# SELECT (EXTRACT(EPOCH FROM now()::timestamp) * 1000)::BIGINT;
     int8      
---------------
 1643326173642
(1 row)



Поэтому если вы хотите чтобы timestamp without timezone как UTC трактовался то надо об этом говорить явно:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
mboguk=# set timezone to UTC;
SET
mboguk=# SELECT (EXTRACT(EPOCH FROM '2022-01-27 20:35:56.962963'::timestamp AT TIME ZONE 'UTC') * 1000)::BIGINT;
     int8      
---------------
 1643315756963
(1 row)

mboguk=# set timezone to 'Europe/Moscow';
SET
mboguk=# SELECT (EXTRACT(EPOCH FROM '2022-01-27 20:35:56.962963'::timestamp AT TIME ZONE 'UTC') * 1000)::BIGINT;
     int8      
---------------
 1643315756963
(1 row)



ну или альтернатива как писали выше приводить к timestamp with timezone
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
mboguk=# set timezone to 'Europe/Moscow';
SET
mboguk=# set timezone to 'UTC';SELECT (EXTRACT(EPOCH FROM '2022-01-27 20:35:56.962963'::timestamp::timestamptz) * 1000)::BIGINT;
SET
     int8      
---------------
 1643315756963
(1 row)

mboguk=# set timezone to UTC;
SET
mboguk=# set timezone to 'UTC';SELECT (EXTRACT(EPOCH FROM '2022-01-27 20:35:56.962963'::timestamp::timestamptz) * 1000)::BIGINT;
SET
     int8      
---------------
 1643315756963
(1 row)



--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Timestamp WO timezone
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]