Order Placed Yesterday: How to Align Dates in the Store API and Reports
A single moment can have different calendar dates in Moscow and UTC. Using a verified example, we examine day boundaries, fractional seconds, and the distinction between delivery date and event time.

In this article
Заказ оформлен 27 сентября в 00:30 по Москве. В выгрузке дата начинается с 26 сентября, а менеджер ищет его в отчёте за 27-е. Заказ не обязательно потерян, и часы сервера не обязательно отстают. Один момент времени может относиться к разным календарным датам в разных часовых поясах.
До поиска ошибки стоит договориться о двух вещах: какое событие считает отчёт и в каком часовом поясе проходят границы его суток. Дата создания, дата оплаты и дата получения уведомления отвечают на разные вопросы. Даже идеально настроенные часы не сделают эти события одним и тем же.
Один момент, две записи
Возьмём учебное событие: 2026-09-27T00:30:00+03:00. Запись указывает местное время и смещение на три часа вперёд относительно UTC. Тот же момент в UTC записывается как 2026-09-26T21:30:00Z. Буква Z обозначает нулевое смещение. При правильном преобразовании событие осталось на месте, поменялось его представление.
Формат RFC 3339 позволяет передать дату, время и смещение однозначно в пределах предусмотренной им модели. Строка без смещения требует дополнительных условий контракта. Если одна сторона понимает её как московское время, а другая как UTC, возникает уже настоящая ошибка на три часа. Исправлять её прибавлением часов ко всем записям опасно: часть данных могла прийти корректно.
Для расследования я бы сопоставил один идентификатор заказа, исходную строку времени, правило её разбора и значение после преобразования. Снимок экрана с одной датой не показывает всю эту цепочку. Полезно также уточнить, округлялось ли время и не была ли его часть отброшена при выгрузке.
Как задать сутки без последней секунды
Для отчёта за 27 сентября 2026 года по Москве нижняя граница — начало 27 сентября, верхняя — начало 28 сентября. Нижнюю включаем, верхнюю исключаем. После преобразования в UTC это интервал от 2026-09-26T21:00:00Z включительно до 2026-09-27T21:00:00Z исключительно. Эти преобразования отдельно проверены в локальной модели Python с базой часовых поясов.
Такое правило удобнее, чем верхняя граница 23:59:59. Событие с долями секунды после 23:59:59 ещё относится к тем же суткам, но может не пройти сравнение с целой последней секундой. Условие «раньше начала следующего дня» охватывает доступную точность времени без угадывания количества девяток.
Соседний отчёт начинается ровно там, где закончился предыдущий. Событие на границе попадает в следующий интервал один раз. Если включить обе границы в обоих отчётах, полночь может учитываться дважды. Если исключить обе — пропасть из обоих. Здесь важен оператор сравнения, а не только красиво подписанный календарь.
Смещение и часовой пояс решают разные задачи
Смещение +03:00 достаточно, чтобы определить момент из приведённой записи. Но для правила «каждый день по местному времени» полезно хранить именованный часовой пояс, например Europe/Moscow. Он связан с правилами базы IANA, включая исторические изменения. Одно фиксированное смещение не описывает все возможные правила региона на любые даты.
В регионах с сезонным переводом часов календарные сутки могут отличаться по продолжительности от 24 часов. Поэтому для отчёта сначала определяют местные начала двух соседних дат, затем переводят обе границы в единую шкалу времени. Простое прибавление 24 часов к уже переведённой нижней границе подходит не для каждого региона и дня.
Среда должна располагать актуальными данными часовых поясов. Например, модуль Python использует системную базу или отдельный пакет данных; отсутствие базы и разные её версии — отдельные условия воспроизводимости. Это не инструкция менять часы рабочего сервера. Расчёт периода отчёта и синхронизация часов — разные проверки.
Дата доставки может вообще не быть моментом
Пожелание покупателя «доставить 27 сентября» может означать календарную дату по правилам магазина. Превращать её без договора в полночь UTC, а затем показывать как местное время — значит добавлять смысл, которого покупатель не задавал. Для такого поля нужен тип даты и явное правило её применения.
И наоборот, факт оплаты требует времени конкретного события, если от него зависит отчёт. Получение уведомления через десять минут не меняет момент оплаты в источнике. При позднем уведомлении система должна по договору либо пересчитать соответствующий период, либо отразить корректировку. Переносить событие в сегодняшний день только потому, что обработчик увидел его сегодня, можно лишь при таком определении показателя.
В приёмке полезно проверить событие непосредственно до полуночи, ровно в полночь и сразу после неё; отдельно — дробную секунду перед верхней границей. Затем повторить передачу того же события с другим корректным смещением. Отчёт должен сохранить результат, если обе записи обозначают один момент.
Для магазина на 1С-Битрикс и внешней учётной системы это вопрос общего контракта обмена, а не выбора одного волшебного формата. Сверьте тип события, исходное время, часовой пояс периода и правила запоздавших данных. После этого фраза «заказ попал во вчера» превращается в проверяемое утверждение: либо неверно выбраны сутки, либо неверно разобрано время, либо сравниваются разные события.
An order was placed on September 27 at 00:30 Moscow time. In the export, the date starts on September 26, yet the manager searches for it in the report for the 27th. The order is not necessarily lost, and the server clock is not necessarily behind. A single moment in time can correspond to different calendar dates in different time zones.
Before hunting for an error, agree on two things: which event the report counts and in which time zone its day boundaries lie. Creation date, payment date, and notification receipt date answer different questions. Even perfectly set clocks will not make these events the same.
One moment, two records
Consider a test event: 2026-09-27T00:30:00+03:00. The record shows local time and a three-hour offset ahead of UTC. The same moment in UTC is recorded as 2026-09-26T21:30:00Z. The letter Z denotes zero offset. With correct conversion, the event remains in place; only its representation changes.
The RFC 3339 format allows unambiguous transmission of date, time, and offset within its defined model. A string without an offset requires additional contractual conditions. If one party interprets it as Moscow time and the other as UTC, a genuine three-hour error arises. Fixing it by adding hours to all records is dangerous: some data may have arrived correctly.
For investigation, I would match a single order ID, the original time string, the parsing rule, and the value after conversion. A screenshot with a single date does not show this entire chain. It is also useful to clarify whether the time was rounded or if part of it was dropped during export.
How to define a day without the final second
For the report dated September 27, 2026, for Moscow, the lower bound is the start of September 27, and the upper bound is the start of September 28. We include the lower bound and exclude the upper bound. After conversion to UTC, this interval is from 2026-09-26T21:00:00Z inclusive to 2026-09-27T21:00:00Z exclusive. These conversions were independently verified in a local Python model with a time zone database.
This rule is more convenient than using 23:59:59 as the upper bound. An event with fractional seconds after 23:59:59 still belongs to the same calendar day but may fail a comparison against the whole final second. The condition "before the start of the next day" covers the available time precision without guessing the number of nines.
The adjacent report starts exactly where the previous one ended. An event on the boundary falls into the next interval only once. If both bounds are included in both reports, midnight may be counted twice. If both are excluded, the event disappears from both. Here, the comparison operator matters, not just a neatly labeled calendar.
Offset and time zone solve different problems
A +03:00 offset is sufficient to determine the moment from the given record. However, for the rule "every day in local time," it is useful to store a named time zone, such as Europe/Moscow. This is linked to IANA database rules, including historical changes. A single fixed offset does not describe all possible regional rules for any given date.
In regions with seasonal clock changes, calendar days can differ in duration from 24 hours. Therefore, for a report, one must first determine the local start times of two consecutive dates, then convert both boundaries to a single time scale. Simply adding 24 hours to the already converted lower boundary does not work for every region or day.
The environment must have up-to-date time zone data. For example, the Python module uses the system database or a separate data package; the absence of a database or different versions constitute separate reproducibility conditions. This is not an instruction to change the clock on a production server. Calculating the reporting period and synchronizing clocks are distinct checks.
Delivery date may not be a specific moment
A buyer's request to "deliver on September 27" may refer to the calendar date according to store rules. Converting it without an agreement to midnight UTC and then displaying it as local time adds meaning the buyer did not specify. Such a field requires a date type and an explicit rule for its application.
Conversely, the fact of payment requires the timestamp of the specific event if the report depends on it. Receiving a notification ten minutes later does not change the payment moment in the source. With a delayed notification, the system must, per the contract, either recalculate the relevant period or reflect a correction. Moving the event to today's date solely because the handler saw it today is permissible only under such a definition of the metric.
During acceptance testing, it is useful to check the event immediately before midnight, exactly at midnight, and immediately after; separately, also check a fractional second before the upper boundary. Then repeat the transmission of the same event with a different correct offset. The report must preserve the result if both records denote the same moment.
For a store on 1C-Bitrix and an external accounting system, this is a matter of the general exchange contract, not the choice of a single magical format. Verify the event type, source time, time zone of the period, and rules for late data. After that, the phrase "the order fell into yesterday" becomes a verifiable statement: either the day was selected incorrectly, the time was parsed incorrectly, or different events are being compared.





Discussion 0
Share your experience and ask questions. Comments without links appear after editorial review.
No comments yet. Start the discussion.