如何将pandas Timedelta添加至Timestamp并限定特定工作时段?
处理工作日特定时段的Timedelta累加问题
这个场景在项目排期、工单时效计算里特别常见,pandas原生的时间加法不会考虑工作时段和工作日限制,所以得自己实现逻辑来精准控制。我给你写一个可复用的函数,完全满足你的需求:
实现思路
核心逻辑是分阶段处理:
- 先把起始时间调整到有效工作时段内(如果起始时间不在工作时段或非工作日,自动跳转到下一个工作时段的开始)
- 逐步累加时长:先算当天剩余的工作时间,如果要加的时长没超过当天剩余时间,直接累加;如果超过,就扣掉当天剩余时长,跳转到下一个工作日继续处理,直到剩余时长为0。
代码实现
import pandas as pd def add_work_time(start_time, delta, work_start=8, work_end=16): # 确保输入是Timestamp类型 start_time = pd.Timestamp(start_time) delta = pd.Timedelta(delta) # 定义工作日:周一到周五(weekday()返回0-4) def is_workday(date): return date.weekday() <= 4 # 第一步:将起始时间调整到最近的有效工作时段 while True: if is_workday(start_time): # 当天是工作日,检查是否在工作时段内 start_of_day = start_time.floor('D') work_start_time = start_of_day + pd.Timedelta(hours=work_start) work_end_time = start_of_day + pd.Timedelta(hours=work_end) if start_time < work_start_time: # 早于上班时间,调整到上班时间 start_time = work_start_time break elif start_time > work_end_time: # 晚于下班时间,跳到下一个工作日的上班时间 start_time = start_of_day + pd.Timedelta(days=1) else: # 在工作时段内,无需调整 break else: # 非工作日,跳到下一个工作日的上班时间 start_time = start_time.floor('D') + pd.Timedelta(days=1) # 第二步:逐步累加剩余时长 remaining_delta = delta while remaining_delta > pd.Timedelta(0): start_of_day = start_time.floor('D') work_end_time = start_of_day + pd.Timedelta(hours=work_end) # 计算当天剩余的工作时间 remaining_today = work_end_time - start_time if remaining_delta <= remaining_today: # 剩余时长能在当天完成,直接累加 return start_time + remaining_delta else: # 剩余时长超过当天剩余时间,扣减后跳转到下一个工作日 remaining_delta -= remaining_today # 找到下一个工作日 next_day = start_of_day + pd.Timedelta(days=1) while not is_workday(next_day): next_day += pd.Timedelta(days=1) start_time = next_day + pd.Timedelta(hours=work_start) # 测试你的例子 start = pd.Timestamp('2019-11-08 14:30:00') add_delta = pd.Timedelta('06:30:00') result = add_work_time(start, add_delta) print(result) # 输出:Timestamp('2019-11-11 13:00:00')
结果说明
你的例子里,起始时间2019-11-08 14:30是周五(工作日):
- 当天剩余工作时间为
16:00 - 14:30 = 1.5小时 - 要加的6.5小时减去1.5小时后,还剩5小时
- 接下来的周六、周日是非工作日,自动跳转到下一个工作日(11月11日周一),从8点开始累加剩余的5小时,最终得到
13:00
如果你的场景里周末也算工作日,可以修改is_workday函数的判断逻辑;如果需要排除特定节假日,可以给函数加一个holidays参数,在判断工作日时额外排除这些日期。
内容的提问来源于stack exchange,提问作者md5sum
相关产品推荐
相关产品推荐

