python按状态统计每个小时的时长

场景
一项业务有多个状态,不同时段分别处于某个状态,按状态统计每个小时内的持续时长。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time ,datetime
def count_hours(hournum,data_list):
    # 状态列表
    status_list = list(set([status for status ,t_start ,t_end in data_list]))
    # 列表时间转换为时间戳
    datanum_map ={status0 :[[time.mktime(time.strptime(j ,"%Y-%m-%d %H:%M:%S")) for j in i[1:]] for i in data_list if i[0 ]==status0]  for status0 in status_list}
    # 计算24小时的开始结束时间、列表中的开始结束时间的并集求和
    # 单行:
    # res ={status0:{hour:sum([max(int(min(hournum[hour]+3600 ,t_end) -max(hournum[hour],t_start)) ,0) for t_start,t_end in datanum_map[status0]]) for hour in range(24)} for status0 in status_list}
    # 拆分:
    res={status0:{} for status0 in status_list}
    for status0 in status_list:
        for hour in range(24):
            count_list = []
            for t_start, t_end in datanum_map[status0]:
                #    max(hournum[hour],t_start)   取 hournum和datanum开始时间最大值作为并集的开始时间
                #    min(hournum[hour]+3600,t_end)   取 hournum+3600和datanum结束时间最大值作为并集的结束时间
                #    max(int(***-***),0)   并集为结束时间-开始时间,如果小于0则取0
                count_list.append(max(int(min(hournum[hour] + 3600, t_end) - max(hournum[hour], t_start)), 0))
            res[status0][hour]=sum(count_list)
    return res

def count_date(date0 ,data_list):
    # 24小时的开始时间转换为时间戳
    # f"{date0} {'0' if hour<10 else ''}{hour}:00:00"  日期+小时+:00:00,其中小时小于10需补0
    # time.mktime(time.strptime(***,"%Y-%m-%d %H:%M:%S"))  将时间字符串转换为时间戳
    hournum = {hour:time.mktime(time.strptime(f"{date0}{' 0' if hour <10 else ' '}{hour}:00:00","%Y-%m-%d %H:%M:%S")) for hour in range(24)}
    return count_hours(hournum,data_list)

def count_today(data_list):
    # 计算每个小时的秒数
    # 24小时的开始时间转换为时间戳
    # datetime.datetime.today().replace(hour=1, minute=0, second=0, microsecond=0) 1点的开始时间对象
    # int(***.timestamp())  将时间字符串转换为时间戳
    hournum = {hour: int(datetime.datetime.today().replace(hour=hour, minute=0, second=0, microsecond=0).timestamp()) for hour in range(24)}
    return count_hours(hournum, data_list)


# 测试数据
today=str(datetime.datetime.today())[:10]
data_list = [(0, "2024-04-06 20:42:47", "2024-04-07 10:42:47"), (1, "2024-04-07 15:42:47", "2024-04-07 20:42:47"),
             (0, f"{today} 15:42:47", f"{today} 20:42:47")]
res = count_today(data_list)
print(today,"\t"+"\n\t\t\t".join([f"{k} {v}" for k, v in res.items()]))

for data0 in ("2024-04-06", "2024-04-07",today):
    res = count_date(data0, data_list)
    print(data0, "\t"+"\n\t\t\t".join([f"{k} {v}" for k, v in res.items()]))

执行结果:

2024-04-10 	0 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 1033, 16: 3600, 17: 3600, 18: 3600, 19: 3600, 20: 2567, 21: 0, 22: 0, 23: 0}
			1 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0}
2024-04-06 	0 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 1033, 21: 3600, 22: 3600, 23: 3600}
			1 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0}
2024-04-07 	0 {0: 3600, 1: 3600, 2: 3600, 3: 3600, 4: 3600, 5: 3600, 6: 3600, 7: 3600, 8: 3600, 9: 3600, 10: 2567, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0}
			1 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 1033, 16: 3600, 17: 3600, 18: 3600, 19: 3600, 20: 2567, 21: 0, 22: 0, 23: 0}
2024-04-10 	0 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 1033, 16: 3600, 17: 3600, 18: 3600, 19: 3600, 20: 2567, 21: 0, 22: 0, 23: 0}
			1 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值