postgresql `в часовом поясе` неправильное поведение? - PullRequest
1 голос
/ 06 июня 2019

У меня есть простая таблица postgresql со следующими данными:

create table ti (
  l text,
  t timestamp without time zone
  );

insert into ti(l, t) values ('now', now());

Я делаю выбор, используя at time zone, я ожидаю UTC + 5.30 hours

select now(), t, t at time zone 'Asia/Kolkata' from ti;

Но это то, чтоЯ получаю:

now|    t|  timezone
2019-06-06T12:11:42.576388Z|    2019-06-06T11:50:48.178689Z|    2019-06-06T06:20:48.178689Z

Вместо сложения вычитается 5.30 часов.

Sqlfiddle здесь

1 Ответ

2 голосов
/ 06 июня 2019

now () возвращает временную метку с часовым поясом.Информация о часовом поясе будет удалена, когда она приведена к временной метке без часового пояса, когда она сохранена в вашей таблице, но фактическое значение, сохраненное в ней, будет зависеть от часового пояса сеанса.

Вы можете довольно легко увидеть это поведение:

postgres=# begin;
BEGIN
postgres=# set time zone utc;
SET
postgres=# insert into test select now();
INSERT 0 1
postgres=# set time zone 'US/Eastern';
SET
postgres=# insert into test select now();
INSERT 0 1
postgres=# select * from test;
             a
----------------------------
 2019-06-06 12:46:10.475424
 2019-06-06 08:46:10.475424
(2 rows)

Немного больше объяснений после вашего комментария.Я думаю, что проблема, с которой вы сталкиваетесь, заключается в преобразовании между меткой времени и меткой времени.Временные метки гораздо менее запутанны, если вы используете только метку времени.Давайте удалим now () из обсуждения, так как это добавляет дополнительный уровень сложности, потому что преобразование из результата now () во временную метку без часового пояса зависит от часового пояса сеанса.

select '2019-06-06 12:00:00UTC'::timestamp with time zone, 
       ('2019-06-06 12:00:00UTC'::timestamp with time zone) at time zone 'Asia/Kolkata';
      timestamptz       |      timezone
------------------------+---------------------
 2019-06-06 12:00:00+00 | 2019-06-06 17:30:00

Я считаю,это то, что вы ожидаете?Мы конвертируем метку времени с часовым поясом в метку времени без часового пояса в конкретном часовом поясе.

То, что вы делаете, похоже на это:

select '2019-06-06 12:00:00UTC'::timestamp with time zone, 
  (('2019-06-06 12:00:00UTC'::timestamp with time zone)::timestamp without time zone) at time zone 'Asia/Kolkata';
      timestamptz       |        timezone
------------------------+------------------------
 2019-06-06 12:00:00+00 | 2019-06-06 06:30:00+00
(1 row)

Я думаю, вы найдете это гораздо менее запутанным, если вы можете хранить метку времени с часовым поясом вместо метки времени без часового пояса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...