TIMESTAMP

Время состоит из разных понятий:

  • дата без времени: день рождения;
  • локальное время без даты: время открытия;
  • локальные дата и время: «2026-07-30 10:00» в еще неизвестной зоне;
  • момент на временной шкале: событие произошло в конкретную секунду;
  • зона с правилами переходов: Europe/Moscow, а не просто смещение.

Одного слова TIMESTAMP недостаточно: семантика зависит от СУБД.

SQL-типы

В PostgreSQL-подобной терминологии:

  • DATE — календарная дата;
  • TIME — время суток;
  • TIMESTAMP WITHOUT TIME ZONE — локальные дата и время без зоны;
  • TIMESTAMP WITH TIME ZONE — момент, нормализуемый СУБД; исходное имя зоны обычно не хранится.

В MySQL TIMESTAMP и DATETIME имеют другое поведение преобразования часового пояса и диапазонов. Нельзя переносить утверждения о размере, диапазоне и конвертации между СУБД.

Практическая модель

Для факта «когда создан заказ» хранят момент:

created_at TIMESTAMP WITH TIME ZONE NOT NULL

Для встречи «09:00 по правилам Europe/Moscow» иногда нужны отдельно локальные дата/время и идентификатор зоны, потому что одно UTC-смещение не содержит будущих правил зоны.

Полуинтервалы

WHERE created_at >= :from_instant
  AND created_at <  :to_instant

Верхняя граница не включается: запрос корректен при любой точности дробных секунд.

Ловушки

  • Не передавать время строкой без формата и зоны.
  • Не хранить «UTC» как неявную договоренность без тестов JDBC и настроек сессии.
  • CURRENT_TIMESTAMP и время приложения могут отличаться.
  • Летнее время дает пропущенные и повторяющиеся локальные времена в некоторых зонах.
  • Часовой пояс сервера, сессии, JDBC и JVM — разные настройки.

Связано: Маппинг даты до Java 8 и старше, Операторы IS NULL BETWEEN IN, Оператор ORDER BY.

Вопросы

Хранит ли timestamp with time zone имя зоны? Обычно хранится/нормализуется момент, а не исходный идентификатор зоны; детали зависят от СУБД.

Почему нельзя всегда хранить только LocalDateTime? Он не определяет единственный момент без зоны/смещения.

Зачем полуинтервал для периода? Чтобы не зависеть от точности последней секунды.

Совпадают ли TIMESTAMP в PostgreSQL и MySQL? Нет, семантика и ограничения различаются.