You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python解析CSV中超23:59的时间值及日期调整方案

解析含超23:59时间值的CSV日期时间列,自动调整日期

问题场景

现有CSV文件包含以下列(均为未转换的object类型):

  • 日期列:格式为月/日/年(如1/1/2000)
  • 开始时间、结束时间列:多数值为小时:分钟格式,但存在部分超过23:59的异常值,这类值格式为小时:分钟:秒(如24:50:00、25:35:00)

使用以下代码解析时触发报错:

time_parser = lambda x: pd.datetime.strptime(x, '%H:%M')
df = pd.read_csv('data.csv', parse_dates = ['StartTime'], date_parser = time_parser)

报错信息:25:39 does not match format %H:%M

需求

  1. 正确解析存在异常时间值的时间列
  2. 若开始时间超过23:59,自动根据超时时长调整对应日期(例如1/1/2000对应24:50:00时,最终日期时间应为1/2/2000 00:50:00)
  3. 明确结束时间列的合理处理方式

解决方案

核心思路:先将日期解析为基础日期,再将时间字符串转换为时间差(Timedelta),通过日期+时间差的方式自动处理跨天情况,避免手动判断小时数的复杂逻辑。

步骤1:读取原始CSV

先不提前解析日期时间,保留原始字符串以便后续处理:

import pandas as pd

df = pd.read_csv('data.csv')

步骤2:编写通用日期时间合并函数

该函数可兼容两种时间格式,自动计算跨天的最终日期时间:

def parse_time_with_date(date_str, time_str):
    # 解析基础日期(月/日/年格式)
    base_date = pd.to_datetime(date_str, format='%m/%d/%Y')
    
    # 处理时间字符串,转换为Timedelta
    try:
        parts = time_str.split(':')
        if len(parts) == 2:
            hours, minutes = map(int, parts)
            time_delta = pd.Timedelta(hours=hours, minutes=minutes)
        elif len(parts) == 3:
            hours, minutes, seconds = map(int, parts)
            time_delta = pd.Timedelta(hours=hours, minutes=minutes, seconds=seconds)
        else:
            return pd.NaT  # 异常格式返回空值
    except (ValueError, AttributeError):
        return pd.NaT  # 解析失败返回空值
    
    # 合并日期与时间差,自动处理跨天
    return base_date + time_delta

步骤3:处理开始时间列

调用函数合并日期列与开始时间列,得到正确的datetime类型值:

# 替换成你的日期列实际名称,比如'Date'
df['StartTime'] = df.apply(lambda row: parse_time_with_date(row['Date'], row['StartTime']), axis=1)

步骤4:处理结束时间列

根据业务场景选择以下两种方式之一:

场景A:结束时间是基于原始日期的时间点

即使开始时间跨天,结束时间仍按原始日期计算,自动调整跨天情况:

df['EndTime'] = df.apply(lambda row: parse_time_with_date(row['Date'], row['EndTime']), axis=1)

场景B:结束时间是相对于开始时间的时长

如果结束时间代表的是从开始时间起的持续时长(而非当天的时间点),先将结束时间转为时间差,再与调整后的开始时间相加:

def parse_to_timedelta(time_str):
    try:
        parts = time_str.split(':')
        if len(parts) == 2:
            hours, minutes = map(int, parts)
            return pd.Timedelta(hours=hours, minutes=minutes)
        elif len(parts) == 3:
            hours, minutes, seconds = map(int, parts)
            return pd.Timedelta(hours=hours, minutes=minutes, seconds=seconds)
        else:
            return pd.NaT
    except (ValueError, AttributeError):
        return pd.NaT

df['EndTime'] = df['StartTime'] + df['EndTime'].apply(parse_to_timedelta)

原代码报错原因

%H格式符仅支持0-23的小时数,无法解析超过23的小时值;而使用Timedelta可以直接将任意小时数转换为时间差,与基础日期相加后自动处理日期进位,无需额外判断逻辑。

内容的提问来源于stack exchange,提问作者Eggy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 18:55:31