#sql #postgresql #timezone
Вопрос:
У меня возникли некоторые проблемы с пониманием того, как работать в Postgres с семантикой часовых поясов: рассмотрим эту таблицу
TABLE MyTable (
MyDate TIMESTAMP NOT NULL,
// other columns
);
И этот запрос
SELECT *
FROM MyTable
WHERE // conditions
AND tstzrange(#{start} ::timestamp with time zone, #{end} ::timestamp with time zone] @> MyDate::timestamp without time zone at time zone 'CET'
Я понимаю, что Postgres
в нем хранится только epoch
значение, т. Е. Информация о часовом поясе никогда не сохраняется, поэтому я понимаю необходимость указания часового пояса для start
и end
поскольку они представляют собой форматированные строки, для которых Postgres необходимо рассчитать epoch
.
Чего я на самом деле не понимаю, так это: MyDate::timestamp without time zone at time zone 'CET'
Postgres знает значение epoch
for MyDate
, так как в нем хранятся их значения, зачем «конвертировать» в часовой пояс ?
Что мы на самом деле здесь говорим и можно ли это упростить ?
Ответ №1:
Postgres никогда не хранит информацию о часовом поясе в timestamp
или timestamptz
. В timestamptz
случае, если сохраняемая метка времени поворачивается до UTC
значения, используя либо информацию о часовом поясе в представленной метке времени, либо значение параметра TimeZone
, а затем сохраняется. В том timestamp
случае, если это не сделано. На выходе a timestamptz
поворачивается назад от UTC
к какой TimeZone
бы ни была настройка или через что at time zone <some_tz>
. В этом timestamp
случае предполагается, что полученное значение является параметром TimeZone
, если вы не переопределите с at time zone <some_tz>
помощью . Лучшие практики — это то, что вы используете timestamptz
.