U
underground dev
@undergrounddev_v1809 подп.
1.4Kпросмотров
5 февраля 2026 г.
questionScore: 1.5K
Есть тут какая-то проблема? CREATE TABLE users ( id BIGSERIAL PRIMARY KEY, close_date TIMESTAMPTZ ); INSERT INTO users (close_date) VALUES (NULL), (NULL); ---------------------------------------------- set timezone = 'UTC'; select from users; set timezone = 'Europe/Moscow'; UPDATE users SET close_date = now() at time zone 'utc'; set timezone = 'UTC'; select from users; Ну очевидно, если спросил - значит есть. Результат будет примерно такой: если выполнить в 20 по мск, то в close_date будет 14 часов по utc. То есть 3 часа исчезнут😬 Вся проблема в том, что 'at time zone' возвращает не timestampz, а timestamp. По итогу: 1. now() at time zone 'utc' отнимаем -3, чтобы сделать utc, возвращает timestamp. 2. при сравнении происходит приведение timestamp к timestampz, postgres зная, что в сессии установлен мск таймзона приводит к utc, то есть еще раз делает -3. Мне это ногу прострелило из-за Npgsql.EnableLegacyTimestampBehavior=true, перенесенного из легаси системы. Потому что при таком флаге, если делаете запрос с DateTimeOffset.UtcNow - это превращается в now() at time zone 'utc', то есть только что созданные записи запрос не видет🚬 Без этого флага будет просто now() и локальная дата просто переведется в utc при присваивании. Кстати да, никогда до этого не задумывался, но timestampz и timestamp работают не так же как и DateTimeOffset и DateTime - оффсет не хранится в БД. Если вы видите в каком-нибудь datagrip или psql, что дата выводиться с оффетом на конце, то это просто для удобного просмотра. Мне повезло 🙂 такого не должно было возникнуть, потому что по дефолту для всех сессий стоит timezone='UTC' в конфиге постгри. Да, если заменить в запросе 'Europe/Moscow' на 'UTC", то отниматься ничего не будет, поведение будет ожидаемым. Ну и бэст практис - это: 1. Генерировать дату на сервисе приводя к UTC(ака DateTimeOffset.UtcNow) 2. Использовать DateTimeOffset в ef core запросах. 3. Использовать timezone='UTC', если необходим Npgsql.EnableLegacyTimestampBehavior=true 4. Если третий пункт не про вас, то просто не писать это вручную now() at time zone 'utc', проверять чтобы его не было. Ладно хоть у меня это на селекте случилось, представляю как было бы весело на вставке данных такое получить🎧 PS: пример может не во всех playground работать, реакцию поставьте что ли🤑
1.4K
просмотров
2419
символов
Да
эмодзи
Нет
медиа

Другие посты @undergrounddev_v1

Все посты канала →
Есть тут какая-то проблема? CREATE TABLE users ( id BIGSERIA — @undergrounddev_v1 | PostSniper