2026, Jan 07 12:06

Сбор второго datetime из поля времени с переходом суток в pandas

Показываем, как в pandas корректно восстановить второй datetime из поля времени: привязать к дате и сдвинуть на сутки, если он меньше стартовой метки. Векторно.

Когда в форме исходные дата и время разделены на поле с датой+временем и последующее поле только со временем, восстановить корректный второй datetime непросто. Если последующее время приходится на после полуночи, оно относится к следующему дню, и простая конкатенация даст метку времени, которая предшествует исходной. Задача — прямо в датафрейме собрать второй datetime, который гарантированно позже первого.

Минимальный пример неоднозначности

Вне датафрейма картина такая: второе значение — это время без даты, поэтому неясно, тот же это день или следующий.

from datetime import date, time, datetime
base_day = date(2025, 1, 1)
base_clock = time(22, 25)
base_stamp = datetime(2025, 1, 1, 22, 25)
next_clock = time(1, 25)

В чем именно проблема

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

Решение напрямую в датафрейме

Подход прост и векторизован. Преобразуйте обе части в datetime, объединив общую дату с каждым временем. Затем условно добавляйте сутки там, где второй кандидат раньше исходной метки.

import pandas as pd
import numpy as np
records = pd.DataFrame({
    "start_date": ["2025-1-1"],
    "start_time": ["10:25 PM"],
    "followup_time": ["1:25 AM"]
})
start_ts = pd.to_datetime(records["start_date"] + " " + records["start_time"])
follow_ts = pd.to_datetime(records["start_date"] + " " + records["followup_time"])
records["ts_start"] = start_ts
records["ts_follow"] = follow_ts + pd.to_timedelta(np.where(follow_ts < start_ts, 1, 0), unit="D")

Так сохраняется требование: вторая метка должна хронологически следовать за первой. Сравнение находит строки, где последующее время логически относится к следующему дню, а векторизованное сложение делает всю операцию эффективной и лаконичной.

Почему это важно

В конвейерах, основанных на формах, дату и время часто разделяют на отдельные поля или собирают несколько времен для одной даты. Без четкого правила перехода суток дальнейшие вычисления, метрики длительности и сортировка могут ломаться: появляются отрицательные интервалы и перепутанный порядок событий. Одна векторизованная проверка избавляет от построчных ветвлений и поддерживает в датафрейме ожидаемую логику движения времени вперед.

Вывод

Нормализуйте поля только со временем, привязывая их к опорной дате, и обеспечивайте хронологию условным сдвигом на сутки. Достаточно одного прохода: парсинг плюс векторизованное сравнение — так логика остается явной, код компактным, а анализ данных надежным.