GH GambleHub

Часові пояси і чутливість

1) Базові принципи

UTC як транспорт і зберігання. Всі серверні таймстемпи і ключі сортування - в UTC. Перетворення в локальний «стінний» час - на краю (edge/UI) або в спеціально виділеному сервісі форматування.
Зона ≠ зміщення.'Europe/Kyiv'- це не просто'UTC + 02:00`: правила змінюються з часом. Зберігайте ідентифікатори IANA (tzdb) в профілі користувача/об'єкта, а не "+ 03:00».
Чітке розрізнення годин.

Wall clock (людський час, схильний до DST).
UTC clock (універсальна шкала).
Monotonic clock (для вимірювання тривалостей і таймаутів). Ніколи не обчислюйте таймаути на «стінних» годинниках.
Ідempotентність і толерантність до тремтіння часу. Системи повинні коректно переживати невеликі стрибки NTP/зміщення.


2) Модель даних і API-контракти

Події: 'occurred _ at'( UTC, RFC 3339),'timezone'( IANA), опціонально'wall _ time'( локальний зі збереженням зміщення при створенні).
Періоди: використовуйте напівзакриті інтервали'[ start, end)'в UTC; для людиночитаних розкладів зберігайте вихідний вираз + зону.
Повторювані правила: серіалізуйте як RRULE/cron-еквівалент + IANA-зона. Планування делегуйте рушію, який розуміє DST.
Формат часу в API: ISO 8601/RFC 3339 з явним'Z'або зміщенням, наприклад'2025-10-31T17:00:00Z`. Не передавайте «плаваючі» рядки без зміщення.
Версіонування: зміна бізнес-правил часу (наприклад, перехід країни на постійний UTC + 1) - це міграція конфігурацій і перерахунок розкладів; враховуйте в схемах версій.


3) Літній час (DST): амбігуїтети і пропуски

Дубльовані локальні часи. Восени локальне "02:30" може трапитися двічі. Планувальник в зоні повинен розрізняти'2025-10-26T02:30 + 03'і'2025-10-26T02:30+02`.
Пропущені локальні часи. Навесні «перескакують» хвилинні інтервали (наприклад,'02:00–03:00'не існує). Планувальник зобов'язаний визначити стратегію: перенести на'03:00', пропустити або виконати «якомога швидше».
Рекомендація: зберігайте завдання як «локальне правило + зона», а фактичні інстанси матеріалізуйте в UTC заздалегідь (rolling window), з фіксацією обраної політики на DST.


4) Leap seconds и time smear

Leap second. Додаткова секунда іноді вставляється в UTC. Більшість бізнес-процесів не повинні «бачити» 23:59:60.
Smear (розмазування). Деякі середовища м'яко розподіляють коригування на вікно (наприклад, ± 12 годин), щоб уникнути стрибка.
Практика: узгодьте єдину політику часу для всього кластера (NTP/смир), логуйте її в метаданих і тримайте в runbook.


5) Планувальники і cron-патерни

Небезпека «простого cron». Класичний cron не знає DST і IANA-зон. Використовуйте рушії, де розклад прив'язаний до зони (Quartz-клас, хмарні Scheduler-сервіси, Kubernetes CronJob із зоною через контролер/адмісіон).
Матеріалізація розкладів. Для надійності матеріалізуйте найближчі N запусків в UTC (наприклад, на 7-30 днів), зберігайте cursor і детермінуйте політику при DST.
Ідempotентність завдань. Ключ deduplication: `(job_id, scheduled_at_utc)`; повторний запуск не повинен дублювати побічні ефекти.
Ковзання годин. При тривалих паузах/інцидентах вирішіть, чи робити catch-up (виконати пропущене) або skip. Конфігуруйте per-job.


6) Час у протоколах і чергах

Подієві шини (Kafka/Pulsar). Зберігайте'event _ time'і'ingest _ time'окремо. Для ретроспективних перерахунків використовуйте'event _ time'.
Ідемпотентні споживачі. При повторній доставці орієнтуйтеся на ключ події і'event _ time', а не на зміщення в партії.
Сортування та вікна. Вікна «за 24 години за локальним часом магазину» обчислюйте як UTC-інтервали, отримані з локальних правил конкретної зони на конкретну дату.


7) Логи, трасування, метрики

Єдиний таймзонний стандарт: всі технічні логи і метрики в UTC (із зазначенням'Z'). Відображення в дашбордах - локалізоване для користувача.
Трасування: передавайте'trace _ start _ utc','duration _ ms'на монотонічних годинниках. Ніколи не віднімайте «стінні» таймстемпи.
Бізнес-звіти: формуйте «добу» в зоні домену (наприклад,'Europe/Paris'для французького податку), а не по UTC. Чітко документуйте.


8) Призначені для користувача профілі та контент

Профіль: `preferred_timezone` (IANA), `preferred_locale`, `currency`, `week_start` (Mon/Sun).
Мультизонні сутності: для команд/організацій зберігайте «зону домену» (наприклад, магазину/юрособи) незалежно від персональної зони учасника.
Нотифікації: обчислюйте «тихі години» в зоні користувача; відправку шедуліті з UTC-вікна, з безпекою при DST.


9) Анти-патерни

Зберігати тільки локальний час без зсуву/зони.
Жорстко прошивати зміщення'+ hh:mm'замість IANA-ідентифікатора.
Вважати тривалості через різницю двох «стінних» таймстемпів.
Планувати по cron без підтримки зон/DST.
Робити аналітику «по добі» в UTC, коли норматив вимагає локальну зону.
Припускати незмінність правил зони (країни змінюють політику часу).


10) Тестування часу

Контрольовані годинники. Ін'єктуйте «годинник» в код (Clock/TimeProvider) для детермінованих тестів.

Набори кейсів:
  • Перехід на літній/зимовий час (дублі/пропуски).
  • Переміщення користувача між зонами (зміна'preferred _ timezone').
  • Зміна правил в tzdb (оновлення бази - регресійні тести).
  • Зміщення NTP, затримана доставка подій.
  • Фаззі-тести. Випадкові зони, дати, формати; порівняння з еталонною бібліотекою.

11) Спостережуваність і експлуатація

Алерти: розсинхронізація NTP, відставання оновлення tzdb, сплески «невиконаних» cron-завдань при DST.
Дашборди: розподіл подій за зонами/локальною добою; лічильники catch-up/skip.
Runbook: процедури при зміні правил часу в юрисдикції; порядок оновлення tzdb; комунікація з власниками розкладів.


12) Патерни реалізації

Time Normalization Gateway. Тонкий сервіс, що нормалізує вхідні часи до RFC 3339 UTC, валідує зони (IANA) і доповнює контекст.
Local-Day Builder. Бібліотека/сервіс, який з «локального дня» і зони будує точні UTC-межі'[ start _ utc, end_utc)', враховуючи DST.
Schedule Materializer. Планувальник, який зберігає правила у вигляді «локальний вираз + зона», матеріалізує майбутні інстанси в UTC і управляє колізіями/пропусками.
Dual-Timestamp Events. Події з полями'occurred _ at _ utc','wall _ time _ local','timezone'. Для UI підставляється локальне, для систем - UTC.


13) Чек-лист архітектора

1. Чи всюди зберігається UTC?
2. Чи є у сутностей IANA-зона і дата-політика домену?
3. Планувальник розуміє DST і матеріалізує інстанси в UTC?
4. Логи/метрики - в UTC; звіти - в доменній зоні?
5. Таймаути/ретраї - на монотонічних годинниках?
6. Оновлення tzdb автоматизовано і моніториться?
7. Тести покривають зміну правил, дублі/пропуски хвилин?


14) Міні-рецепти (псевдокод)

Перетворення локального «робочого дня» в UTC-інтервал


function localDayToUtcInterval(dateLocal, tz):
startLocal = combine(dateLocal, 00:00) in tz endLocal  = startLocal + 1 day startUtc  = toUTC(startLocal) // учитывает DST endUtc   = toUTC(endLocal)
return [startUtc, endUtc)

Матеріалізація повторюваного розкладу


inputs: rrule, tz, windowStartUtc, windowEndUtc for each localOccurrence in expand(rrule, tz, [windowStartUtc, windowEndUtc] projected to tz):
emit occurrence { scheduled_at_utc = toUTC(localOccurrence), tz }

Ідемпотентний ключ запуску задачі


dedupe_key = hash(job_id + scheduled_at_utc.toString())

15) Безпека та відповідність

Аудит: зберігайте обидві проекції часу (UTC і локальну), щоб узгодити призначені для користувача претензії ("мені обіцяли до 23:00 по Лімі") з серверною хронологією.
Регуляторика: звітні періоди формуються в необхідних зонах (податки, відповідальні ігрові ліміти, маркетингові обмеження «по годинах»).
Приватність: часовий пояс - персональні налаштування, але не точно ідентифікуючі дані; обробляйте в рамках загальних політик конфіденційності.


Висновок

«Чутливість до часу» - це не про формат дати, а про архітектурні межі відповідальності: де зберігати, де перетворювати, як планувати і як доводити коректність. Уніфікація на рівні UTC, явні IANA-зони, грамотні планувальники, подвійні таймстемпи і монотонічні годинники перетворюють час з джерела інцидентів в передбачуваний інфраструктурний сервіс.


Пов'язані статті розділу «Архітектура та Протоколи» (рекомендується):
  • GeoDNS і гео-маршрутизація; Балансування навантаження; Спостережуваність подій у часі; Cron-патерни і матеріалізація розкладів; Регіональні обмеження та локальні звітні добу.
Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.