Выручка за день в pandas: сначала часовой пояс, потом дата

У платёжного сервиса и отдела продаж не сходится выручка за понедельник. Общая сумма за две недели совпадает, пропущенных оплат нет. Расхождения сосредоточены возле полуночи. Частая причина: сервис хранит время в UTC, а бизнес считает день в локальном часовом поясе.

Если сначала взять дату UTC, а затем попытаться поправить готовый дневной отчёт, восстановить правильное распределение уже не получится. Внутри агрегата потеряно время конкретной оплаты. Надёжный порядок — прочитать момент события, перевести его в пояс отчёта и только после этого выделить календарный день.

Различать момент времени и надпись на часах

Значение 2026-10-01T21:30:00Z содержит известный момент: буква Z означает UTC. В Москве в это время уже 00:30 второго октября. Одна и та же оплата относится к разным календарным датам в двух поясах, хотя её абсолютное время не меняется.

В pandas tz_convert переводит уже известный момент между поясами. Метод tz_localize нужен для другого действия: указать пояс времени, у которого его ещё нет. Применить UTC к наивной московской отметке означает объявить другой момент. Поэтому сначала выясните контракт источника, особенно если в CSV нет суффикса Z или смещения.

Рабочий пример дневного отчёта

import pandas as pd

payments = pd.DataFrame({
    'paid_at': ['2026-10-01T20:30:00Z',
                '2026-10-01T21:30:00Z',
                '2026-10-02T07:00:00Z'],
    'amount': [100, 200, 300],
})
instants = pd.to_datetime(payments['paid_at'], utc=True, errors='raise')
payments['report_day'] = (
    instants.dt.tz_convert('Europe/Moscow').dt.strftime('%Y-%m-%d')
)
report = payments.groupby('report_day', as_index=False)['amount'].sum()
print(report.to_string(index=False))
assert report['amount'].tolist() == [100, 500]
assert report['amount'].sum() == payments['amount'].sum()

Первого октября отчёт покажет 100, второго — 500. Платёж на 200 пересёк календарную границу. Если извлечь дату прямо из исходной UTC-строки, получится 300 в первый день и 300 во второй. Общая сумма 600 скрывает ошибку распределения.

Строковая дата здесь удобна для вывода и группировки. Для дальнейших расчётов с календарём можно сохранить локализованное datetime-поле и получать день через соответствующие временные операции. Важно, чтобы пояс применялся до округления или извлечения даты.

Как проверить чужую выгрузку

Возьмите несколько платежей за три часа до UTC-полуночи и несколько сразу после неё. Для Москвы именно около 21:00 UTC начинается следующий календарный день. Сравните их с первичными карточками оплат, где известен пояс интерфейса.

Проверьте, какой момент считает бизнес: создание заказа, успешную оплату или поступление денег на расчётный счёт. Часовой пояс исправляет распределение выбранного события, но не делает разные события одинаковыми. Если возвраты учитываются датой возврата, храните эту дату отдельно от даты исходной продажи.

Для международной сети одного пояса может быть недостаточно. Дневная выручка магазина считается в его локальном времени, а управленческий отчёт сети может использовать общий пояс. Зафиксируйте правило в названии поля и описании показателя. В регионах с сезонным переводом часов используйте имя зоны, а не постоянное прибавление часов: смещение зависит от даты.

Не превращайте неразобранное время в пропуск ради завершения отчёта. Сначала соберите ошибочные исходные строки и выясните их формат. В примере errors='raise' останавливает расчёт, если источник прислал неподходящее значение, чтобы повреждённая оплата не исчезла незаметно.

От календарной границы к анализу

Попробуйте задачи по датам и rolling в pandas: в них важно понимать порядок преобразований и границы периода.

После исправления дат можно сравнивать периоды и искать причины изменения продаж. В курсе «Практическая аналитика данных» вы формулируете метрику, проверяете исходные данные, разбираете продажи и готовите дашборд DataLens с объяснением результата. Откройте программу и выберите pandas-маршрут для своего следующего отчёта.

Продолжить на практике

  • Практическая аналитика данных ↗

    Превратите знания SQL или Python в аналитическую работу: проверяйте данные, считайте бизнес-метрики, стройте дашборды и объясняйте выводы на трёх прикладных кейсах.