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

Python业务工作时长计算函数的修改优化及输入适配需求

Python工作时长计算函数修改方案

需求说明

编写无需类定义的原生Python函数,实现业务工作时长计算,需支持小时单位输出,并适配以下输入格式:

get_work_hours("2019-12-02 09:30:00", "2019-12-07 12:15:00", worktiming=[9, 17])

原代码核心问题分析

  1. 输入处理错误:直接将字符串输入当作datetime对象操作,未做格式解析
  2. 对象初始化错误:dt_start = datetime1.datetime属于非法写法,无法正确获取datetime实例
  3. 缺失依赖函数:未定义is_weekend函数,且周末判断逻辑错误(Python的weekday()返回0-6,对应周一到周日,原代码的[6,7]不符合规范)
  4. 日期循环逻辑漏洞:current_day == dt_start会因时间部分差异导致判断失效,无法正确计算首日时长
  5. 边界时间处理错误:首尾日的工作时段修正存在日期参数误用,导致时长计算偏差
  6. 输出单位不符合要求:仅返回分钟数,未支持小时计算

修改后的完整代码

import datetime

def get_work_hours(start_str, end_str, worktiming=[9, 17]):
    # 解析输入时间字符串为datetime对象,捕获格式错误
    try:
        dt_start = datetime.datetime.strptime(start_str, "%Y-%m-%d %H:%M:%S")
        dt_end = datetime.datetime.strptime(end_str, "%Y-%m-%d %H:%M:%S")
    except ValueError:
        raise ValueError("输入时间格式错误,请使用'YYYY-MM-DD HH:MM:SS'格式")
    
    day_hours = worktiming[1] - worktiming[0]
    day_seconds = day_hours * 3600  # 单个工作日的总秒数
    worktime_in_seconds = 0

    # 处理结束时间早于开始时间的无效场景
    if dt_end <= dt_start:
        return 0.0

    # 定义周末判断逻辑:周六(5)、周日(6)为周末
    def is_weekend(dt):
        return dt.weekday() in [5, 6]

    if dt_start.date() == dt_end.date():
        # 同一天内的工作时长计算
        if is_weekend(dt_start):
            return 0.0
        
        # 修正开始时间至上班时段
        work_start = datetime.datetime(dt_start.year, dt_start.month, dt_start.day, worktiming[0], 0)
        actual_start = max(dt_start, work_start)
        
        # 修正结束时间至下班时段
        work_end = datetime.datetime(dt_end.year, dt_end.month, dt_end.day, worktiming[1], 0)
        actual_end = min(dt_end, work_end)
        
        # 修正后无有效工作时长则返回0
        if actual_start >= actual_end:
            return 0.0
        
        worktime_in_seconds = (actual_end - actual_start).total_seconds()
    else:
        # 跨多天的工作时长计算
        # 处理第一天的有效时长
        if not is_weekend(dt_start):
            work_start = datetime.datetime(dt_start.year, dt_start.month, dt_start.day, worktiming[0], 0)
            actual_start = max(dt_start, work_start)
            work_end = datetime.datetime(dt_start.year, dt_start.month, dt_start.day, worktiming[1], 0)
            if actual_start < work_end:
                worktime_in_seconds += (work_end - actual_start).total_seconds()
        
        # 处理中间完整的工作日
        current_day = dt_start + datetime.timedelta(days=1)
        while current_day.date() < dt_end.date():
            if not is_weekend(current_day):
                worktime_in_seconds += day_seconds
            current_day += datetime.timedelta(days=1)
        
        # 处理最后一天的有效时长
        if not is_weekend(dt_end):
            work_start = datetime.datetime(dt_end.year, dt_end.month, dt_end.day, worktiming[0], 0)
            actual_start = max(work_start, datetime.datetime(dt_end.year, dt_end.month, dt_end.day, 0, 0))
            work_end = datetime.datetime(dt_end.year, dt_end.month, dt_end.day, worktiming[1], 0)
            actual_end = min(dt_end, work_end)
            if actual_start < actual_end:
                worktime_in_seconds += (actual_end - actual_start).total_seconds()
    
    # 转换为小时单位,保留两位小数
    return round(worktime_in_seconds / 3600, 2)

# 测试示例
print(get_work_hours("2019-12-02 09:30:00", "2019-12-07 12:15:00", worktiming=[9, 17]))

关键修改说明

  • 输入格式适配:新增字符串转datetime对象的逻辑,支持指定输入格式,同时捕获格式错误异常
  • 修复核心逻辑错误:移除原代码中非法的datetime初始化写法,替换为正确的实例创建方式
  • 完善周末判断:实现符合Python规范的周末识别逻辑,确保非工作日时长不被计算
  • 优化循环逻辑:将日期比较从完整datetime对象改为仅比较日期部分,避免时间差异导致的逻辑失效
  • 修正边界时间处理:统一首尾日的工作时段修正逻辑,确保仅计算有效工作时长
  • 支持小时计算:最终返回值从分钟转换为小时,保留两位小数,满足需求
  • 增强鲁棒性:新增无效时间顺序的判断,避免出现负数时长;添加异常处理提升代码容错性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:10:29