Если слоты записи отображаются в неправильном часовом поясе, клиент выбирает одно время, а сотрудник видит другое. Ошибка может появляться только у путешествующих пользователей, отдельных филиалов или на датах перехода летнего времени.
Нужно разделить три понятия: абсолютный момент, часовой пояс филиала и локальное отображение пользователя. Добавление фиксированных трех часов в одном месте не исправляет модель и ломает другие регионы.
Зафиксируйте время на каждом этапе
Проследите один слот от графика сотрудника до сохраненной записи и уведомления.
- Список показывает верно, а подтверждение сдвинуто.
- Администратор и клиент видят разные часы.
- Ошибка появляется только после смены часового пояса устройства.
- Слот на границе DST отсутствует или дублируется.
Почему возникает проблема
Дата без timezone интерпретируется по-разному в базе, backend, JavaScript и календаре.
- Backend возвращает локальное время без offset.
- База хранит смесь UTC и локальных значений.
- Frontend повторно применяет смещение браузера.
- График филиала рассчитывается в timezone сервера.
- Внешний календарь использует другой идентификатор зоны.
Пошаговая диагностика
Используйте конкретную дату и записывайте ISO-значение вместе с timezone.
- Сверьте timezone филиала, пользователя, сервера и базы.
- Проверьте исходный timestamp и offset в API.
- Сравните создание слота, выбор, сохранение и уведомление.
- Повторите тест на зимней и летней дате.
- Проверьте импорт и экспорт внешнего календаря.
Храните момент и зону раздельно
Абсолютная запись хранится в UTC, а бизнес-расписание привязано к именованной зоне филиала.
- Начало записи хранится как однозначный момент.
- Филиал хранит IANA timezone, а не фиксированный offset.
- Frontend получает ISO 8601 с явным смещением.
- Уведомление указывает зону или понятное локальное время.
Как исправить проблему
Исправьте контракт даты целиком, а не отдельное отображение.
- Нормализуйте хранение новых записей в UTC.
- Рассчитывайте рабочие окна в зоне филиала.
- Передавайте offset или Z в каждом API timestamp.
- Уберите ручные прибавления часов на frontend.
- Мигрируйте старые данные только после определения их исходной зоны.
Как проверить результат
- Один слот означает одинаковый момент для клиента и сотрудника.
- Смена timezone устройства меняет только представление.
- DST-даты не создают невозможные или двойные записи.
- Письма и календари показывают согласованное время.
Типичные ошибки
- Хранить локальную дату без timezone.
- Использовать фиксированный offset для региона с DST.
- Применять смещение и на backend, и на frontend.
- Массово сдвигать старые записи без аудита.
Как предотвратить повторение
- Зафиксируйте контракт даты в API.
- Добавьте тесты нескольких зон и DST.
- Храните именованную timezone филиала.
- Мониторьте расхождения календарных интеграций.
Когда нужна помощь
Если слоты смещаются по времени, я прослежу timestamp через базу, API, frontend и календарь, исправлю модель UTC и timezone и помогу безопасно нормализовать старые записи.