给定某日的上班时间段,计算当日的工作时间总时长(Python)

很多统计/考核场景会遇到这种需求:一天里上班不是连续的,比如上午一段、下午一段。我们希望输入这些"上班时间段",自动算出当天总工作时长(单位:小时)。

比如某单位作息:

上午:08:30--12:00

下午:14:30--18:00

那么当天工作时长应该是:3.5 + 3.5 = 7.0 小时。

下面用 Python 标准库 datetime 来实现,优点是:严谨、可扩展、不会因为手算出错。

1.思路说明(为什么不用 time 直接相减?)

我们在代码里会用到 datetime、date、time:

time(8,30):只表示"08:30",没有日期

date(2000,1,1):只表示"2000-01-01",没有时分秒

datetime:日期 + 时间,比如 "2000-01-01 08:30:00"

关键点:time 不能直接相减,例如:

time(12, 0) - time(8, 30) # ❌ 不允许

因为它们没有日期,跨天怎么处理并不明确。

解决办法是:给 time 搭配一个固定的日期(随便哪天都行,只要不跨午夜),用 datetime.combine() 拼成 datetime,然后就可以相减得到时间差了。

2代码实现

python 复制代码
from datetime import datetime, date, time

## ① 定义上班时间段(可以有多段)
工作时段列表 = [
    (time(8, 30), time(12, 0)),
    (time(14, 30), time(18, 0)),
]

def 计算单日工作小时(时段列表):
    """
    输入:时段列表,例如 [(08:30, 12:00), (14:30, 18:00)]
    输出:当天工作总时长(小时,float)
    """
    base_day = date(2000, 1, 1)  # 随便选一天作为基准(占位用)
    total = 0.0

    # ② 逐个时间段计算时长并累加
    for start_t, end_t in 时段列表:
        # 把 time 拼到同一天上,得到 datetime(这样才能做减法)
        start_dt = datetime.combine(base_day, start_t)
        end_dt = datetime.combine(base_day, end_t)

        # ③ 做个保护:如果结束时间 <= 开始时间,说明这个时间段写错了
        if end_dt <= start_dt:
            raise ValueError(f"时间段有问题:{start_t} ~ {end_t},结束时间必须晚于开始时间")

        # ④ datetime 相减得到 timedelta,再转成小时
        hours = (end_dt - start_dt).total_seconds() / 3600
        total += hours

    return total
# ⑤ 计算并输出结果
单个工作日小时数 = 计算单日工作小时(工作时段列表)
print(单个工作日小时数)  # 7.0

3. 逐行解释

(1)工作时段列表是什么?

python 复制代码
工作时段列表 = [
    (time(8, 30), time(12, 0)),
    (time(14, 30), time(18, 0)),
]

这是一个列表,里面有多个"时间段"。每个时间段用 (开始时间, 结束时间) 表示。

你可以随时增加第三段、第四段,比如晚上加班:

工作时段列表 = [

(time(8, 30), time(12, 0)),

(time(14, 30), time(18, 0)),

(time(19, 0), time(21, 0)),

]

函数不需要改,照样能算。

(2)为什么要 datetime.combine(base_day, start_t)?

start_t 只是一个 time,不能相减。

我们用 combine 把它拼到同一天 base_day 上:

08:30 变成 2000-01-01 08:30:00

12:00 变成 2000-01-01 12:00:00

这样就能:

end_dt - start_dt

得到时间差。

(3)total_seconds()/3600 为啥这么写?

end_dt - start_dt 得到的是 timedelta(时间差对象),它里面存的是"多少天、多少秒"等信息。

.total_seconds() 得到总秒数

除以 3600 把"秒"转成"小时"

举个例子:

08:30--12:00 是 3.5 小时

3.5 * 3600 = 12600 秒

所以 total_seconds()/3600 = 3.5

  1. 输出结果验证

用你这个作息:

上午:08:30--12:00 = 3.5 小时

下午:14:30--18:00 = 3.5 小时

合计 = 7.0 小时

所以输出:

7.0

5. 常见坑提醒

时间段写反了(例如 18:00--14:30),代码会直接报错提醒你。

跨天时段(例如 22:00--02:00)这段代码不支持;如果真有夜班跨天,需要另外处理(可以把它拆成两段:22:00--24:00 + 00:00--02:00)。

午休不算工作时间:我们通过把上午、下午分成两段自然解决了。

相关推荐
掘金安东尼2 小时前
顶层元素问题:popover vs. dialog
前端·javascript·面试
C嘎嘎嵌入式开发2 小时前
NLP 入门:从原理到实战的个人经验总结
人工智能·python·自然语言处理·nlp
咖啡の猫2 小时前
Python字典元素的增、删、改操作
java·开发语言·python
掘金安东尼2 小时前
React 的新时代已经到来:你需要知道的一切
前端·javascript·面试
Swizard2 小时前
Python 并不慢,是你看不懂:拆解 CPython 虚拟机背后的魔法引擎
python
掘金安东尼2 小时前
React 已经改变了,你的 Hooks 也应该改变
前端·vue.js·github
Codebee2 小时前
A2UI vs OOD全栈方案:AI驱动UI的两种技术路径深度解析
前端·架构
掘金安东尼2 小时前
TypeScript 严格性是非单调的:strict-null-checks 和 no-implicit-any 的相互影响
前端·面试
Lucky小小吴2 小时前
JAVA漫谈反序列化篇——笔记
java·开发语言·笔记