Восьмого марта 2026 года Британская Колумбия отказалась от перехода на зимнее время и навсегда осталась в Pacific Daylight Time (UTC-7). Для базы данных это катастрофа. Если вы храните будущие встречи как timestamptz в America/Vancouver, то после обновления пакета tzdata (а его обновляют каждые несколько месяцев) все даты с ноября по март сдвинутся на час.
Суть проблемы: timestamptz на самом деле хранит только UTC. Часовой пояс используется как калькулятор — при вставке локальное время переводится в UTC по действовавшим тогда правилам, а при чтении обратно — по текущим. Если правила изменились, пользователь увидит не то время, которое ввёл. Пример: кто-то забронировал приём на 10:00 10 ноября 2026 года. Система сохранила 2026-11-10 18:00:00+00. После обновления tzdata этот же момент будет показываться как 11:00 по местному времени.
Решение — dual-column pattern. Заводите три колонки: local_time (без зоны), timezone_name (IANA-имя) и вычисляемую starts_at_utc типа timestamptz. Первые две хранят то, что ввёл пользователь: «встреча в 10 утра в Ванкувере». Третья — расчётный UTC-момент на основе текущих правил. Поскольку Postgres не умеет делать GENERATED колонки с timestamptz (оно считается неиммутабельным из-за меняющихся правил), придётся написать триггер BEFORE INSERT OR UPDATE, который присваивает starts_at_utc = local_time AT TIME ZONE timezone_name.
После каждого обновления tzdata нужно пересчитать starts_at_utc для будущих записей в изменившихся часовых поясах простым UPDATE. Для уже обновлённых систем, где данные могли сохраниться по старым правилам, придётся разбираться: найти момент обновления, выявить некорректные строки по updated_at, уведомить пользователей о сдвиге, дать возможность подтвердить или отменить новое время. А потом — опять уведомлять перед бывшей датой перехода.
RFC 9557 (формат с зоной в квадратных скобках) проблему не решает — в стандарте прямо написано, что он не предназначен для случаев, когда будущее локальное время меняется из-за пересмотра часовых поясов. Так что dual-column pattern остаётся правильным выбором для календарных событий, юридических сроков и всего, где важна «локальная воля» пользователя. Для логов, финансовых транзакций и дат в прошлом хватит обычного timestamptz.
Британская Колумбия — 5,8 млн человек. Если ваша база работала с этим часовым поясом и вы уже обновили tzdata, готовьтесь к миграции.