Короткий ответ
Храните момент времени в UTC, а бизнес-день вычисляйте после явного преобразования в согласованную таймзону. Часовую зону метрики нужно документировать.
Как это работает подробнее
Операция DATE(timestamp) использует календарную дату переданного значения. Если источники записывают локальное время без зоны, события одного момента могут попасть в разные дни.
- UTC. Удобен как единая шкала хранения и обмена.
- Локальная зона. Нужна при расчёте суток пользователя, магазина или бизнеса.
Пример кода
events_by_moscow_day.sql
SELECT DATE(event_ts AT TIME ZONE 'Europe/Moscow') AS business_date,
COUNT(*) AS event_count
FROM events
GROUP BY business_date
ORDER BY business_date;Что использовать на практике
- Храните timezone-aware timestamp и определяйте, чьи именно сутки использует отчёт.
- Тестируйте границы около полуночи и переходов на летнее время для соответствующих регионов.
Подводные камни
- Двойная конвертация. Неверное предположение о типе исходного timestamp сдвинет время дважды.
- Фиксированный офсет. Значение вроде UTC+3 не заменяет именованную зону в регионах с DST.