#postgresql #datetime #timezone
#postgresql #datetime #Часовой пояс
Вопрос:
Я на PostgreSQL версии 11.10, и у TimeZone
меня установлено значение . UTC
Когда я говорю select '2021-02-16 17:45 00' at time zone 'America/New_York';
, я получаю 2021-02-16 12:45:00
, что правильно и ожидаемо.
Однако, когда я говорю select '2021-02-16 17:45' at time zone 'America/New_York';
, я получаю тот же результат.
Похоже, что обе строки принудительно привязаны к timestamp with time zone
, что кажется мне немного нелогичным в случае последнего. Почему PostgreSQL ведет себя так? Задокументировано ли это в руководстве (я просмотрел следующие места: В ЧАСОВОМ ПОЯСЕ, затем типы даты / времени, а также интерпретация ввода даты / времени и обработка недопустимых или неоднозначных временных меток, все безрезультатно).
Комментарии:
1. Потому что у вас есть
TimeZone = UTC
then'2021-02-16 17:45 00'
и'2021-02-16 17:45'
то же самое, что и Postgres, используетTimeZone
параметр в качестве tz, когда он не указан.2. Смотрите здесь Временные метки 8.5.1.3. Метки времени: «PostgreSQL никогда не проверяет содержимое литеральной строки перед определением ее типа и, следовательно, будет рассматривать оба вышеперечисленных параметра как временные метки без часового пояса». Так
'2021-02-16 17:45 00'
становится'2021-02-16 17:45'
.
Ответ №1:
Поскольку для вашего TimeZone
параметра установлено значение UTC
, любая временная метка без указанного часового пояса будет интерпретироваться как локальная для часового пояса UTC. Поскольку вы запрашиваете, чтобы временная метка интерпретировалась как America/New_York
, Postgres сначала интерпретирует временную метку как временную метку UTC, а затем выполняет вычисления для ее преобразования America/New_York
.
Обратите внимание, что если вы на самом деле смотрите на типы, отправляемые в Postgres, это не timestamp with timezone
принудительно, если вы не укажете это:
edb=# select pg_typeof('2021-02-16 17:45' at time zone 'America/New_York');
pg_typeof
-----------------------------
timestamp without time zone
(1 row)
edb=# select pg_typeof('2021-02-16 17:45 00' at time zone 'America/New_York');
pg_typeof
-----------------------------
timestamp without time zone
(1 row)
edb=# select pg_typeof('2021-02-16 17:45 00'::timestamptz at time zone 'America/New_York');
pg_typeof
-----------------------------
timestamp without time zone
(1 row)
edb=# select pg_typeof('2021-02-16 17:45 00'::timestamptz);
pg_typeof
--------------------------
timestamp with time zone
(1 row)
edb=# select pg_typeof('2021-02-16 17:45 00'::timestamp);
pg_typeof
-----------------------------
timestamp without time zone
(1 row)