Даты и время в коде - хранение, пояса, периоды
Дата - самое обманчивое поле в проекте. Пока сайт живёт в одном часовом поясе, работает почти любой код; расхождения начинаются позже.
Что общего у этих задач
Дата в коде - объект, а не строка. Строка зависит от формата и языка, а объект сравнивается, складывается и уходит в запрос без сюрпризов.
Хранится всё во времени сервера, а показывается со сдвигом. Сдвиг зависит от настроек пользователя, и именно он даёт разницу между тем, что видит менеджер и что лежит в базе.
Границы периодов считают явно. «Вчера», «этот месяц» и «за смену» - это конкретные две отметки времени, а не понятие, которое код угадает сам.
Расхождения по времени всплывают в отчётах. Заказ, попавший во вчерашний день у менеджера и в сегодняшний у бухгалтера, - это всегда вопрос границ суток и часового пояса, а не ошибка выборки.
С чего начать
Начинают с одного вопроса: в каком поясе живёт проект и его сотрудники. Если поясов несколько, решают, чей день считается днём отчёта, и записывают это в описание задачи.
Дальше приводят код к работе с объектами дат вместо строк. Строковые сравнения переживают ровно до первой смены формата или языка сайта.
Последним проверяют границы периодов на живых данных. Заказ, оформленный ровно в полночь, показывает, правильно ли посчитаны сутки в отчёте.
Решения подтемы
- Даты в коде: объект, часовой пояс, фильтр по периоду - чтение и запись дат, сдвиг пояса и границы периодов.
- Вывод дат на витрине: падежи, форматы сайта, относительное время - склонение месяца и формат сайта.
- Дата сохранилась не та: разбор причин - пояс пользователя, разбор ввода, границы периода, тип поля.
- Рабочий календарь: график, праздники, расчёт срока - хранение календаря, расчёт рабочих дней, отсечка, вывод.
- Запись на услугу: слоты, занятость, защита от двойной брони - хранение броней, сборка слотов дня, отсев занятых, гонка заявок.
- Дата и время изнутри: хранение, пояса, форматы - формат хранения, пояс сервера и сайта, преобразование при чтении.
Частые вопросы
В каком времени дата лежит в базе?
Во времени сервера, без пояса пользователя. Сдвиг добавляется при выводе, а не при хранении.
Почему у менеджеров разное время заказа?
У них разные часовые пояса в профиле. Показ сдвигается, сама запись при этом одна.
Можно ли фильтровать по дате строкой?
Можно, но формат строки должен совпасть в точности. Объект даты снимает этот вопрос.
Как посчитать «за вчера»?
Двумя явными отметками: начало и конец суток. Иначе результат зависит от времени запуска.
Связанные темы
- Ядро D7 - устройство ядра целиком
- Дата, число и HTML в свойствах: хранение, вывод, фильтр - даты в свойствах инфоблоков
- Отчёты по заказам: агрегаты, группировка, выгрузка - где границы суток важнее всего
- Свой агент и задание по расписанию: создание, шаг, защита - код, который зависит от времени запуска
- Раздел Ядро и D7