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

使用PowerShell计算CSV中服务过去30天的运行时长

计算服务过去30天Running状态总时长的解决方案

这个场景我常碰到,要搞定这种多次状态切换的运行时长计算,核心是先把服务的状态时间线梳理清楚,按时间顺序配对Running的起止节点,再逐个计算有效时长累加就行。下面给你一步步拆解:

第一步:数据预处理(关键前提)

  • 过滤+排序:先从CSV里筛选出目标服务的所有记录,然后严格按时间戳从小到大排序——状态是随时间变化的,乱序的话根本没法配对起止点。
  • 时间格式转换:把CSV里的字符串时间(比如"2019/10/20 07:49:40,836 GMT")转换成可计算的日期时间类型(比如Python的datetime、SQL的TIMESTAMP),注意处理逗号分隔的毫秒和GMT时区,避免计算误差。

第二步:梳理Running状态的时间周期

遍历排序后的记录,配对每个Running的开始和结束时间,要注意几种边界情况:

  • 如果第一条记录是Running:它的开始时间就是这条的时间,结束时间要么是下一条Shutdown的时间,要么是当前时间(如果之后没有Shutdown记录,说明服务一直运行到现在)。
  • 如果第一条记录是Shutdown:直接跳过,因为我们只关心Running的时间段。
  • 连续的相同状态(比如两条连续的Running):只保留最早的那条作为开始时间,后面的重复状态可以忽略——状态没变化,不需要重复计算。

第三步:计算有效时长并累加

对每个配对的[开始时间, 结束时间],先判断这个时间段是否和“过去30天”有重叠(比如如果开始时间在30天前,只算从30天前到结束时间的部分),然后计算时间差,最后把所有符合条件的时长加起来。

举个实际例子(用你给的Service1数据)

假设当前时间是2019/10/25(过去30天范围是2019/09/25 ~ 2019/10/25):

  1. 第一个Running周期:2019/10/10 → 2019/10/15 Shutdown,时长5天。
  2. 第二个Running周期:2019/10/20 → 当前时间2019/10/25,时长5天。
    总运行时长就是10天。

具体实现示例(Python)

下面是一段可直接参考的代码,处理了各种边界情况:

from datetime import datetime, timedelta
import csv

def calculate_running_duration(service_name, csv_file, days=30):
    # 计算过去30天的起始时间点
    cutoff_time = datetime.now() - timedelta(days=days)
    service_records = []

    # 读取CSV并过滤目标服务的记录,转换时间格式
    with open(csv_file, 'r', newline='') as f:
        reader = csv.DictReader(f)
        for row in reader:
            if row['Name'] == service_name:
                # 处理带逗号的毫秒和GMT时区,转换成datetime对象
                time_str = row['Time'].strip('"').replace(',', '.')
                try:
                    record_time = datetime.strptime(time_str, "%Y/%m/%d %H:%M:%S.%f GMT")
                except ValueError:
                    # 兼容没有毫秒的情况
                    record_time = datetime.strptime(time_str, "%Y/%m/%d %H:%M:%S GMT")
                service_records.append({'status': row['Status'], 'time': record_time})
    
    # 按时间从小到大排序
    service_records.sort(key=lambda x: x['time'])

    total_duration = timedelta(0)
    current_running_start = None

    for record in service_records:
        if record['status'] == 'Running':
            # 记录Running的开始时间(仅当之前没有未结束的Running时)
            if not current_running_start:
                current_running_start = record['time']
        elif record['status'] == 'Shutdown':
            # 计算当前Running周期的时长
            if current_running_start:
                # 只取和过去30天重叠的部分
                period_start = max(current_running_start, cutoff_time)
                period_end = record['time']
                if period_start < period_end:
                    total_duration += period_end - period_start
                current_running_start = None
    
    # 处理最后一条状态是Running的情况(服务至今仍在运行)
    if current_running_start:
        period_start = max(current_running_start, cutoff_time)
        period_end = datetime.now()
        if period_start < period_end:
            total_duration += period_end - period_start
    
    return total_duration

# 调用示例
total_time = calculate_running_duration('Service1', 'service_status.csv')
print(f"Service1在过去30天的总运行时长:{total_time}")

额外注意事项

  • 时区问题:如果你的系统时区和数据里的GMT不一致,记得做时区转换,避免时间差计算错误。
  • 重复状态处理:如果CSV里有连续的相同状态记录(比如连续两条Running),代码里已经做了跳过处理,确保每个Running周期只计算一次。
  • 截止时间定义:如果“过去30天”的截止时间不是当前时间,而是某个指定时间点,把代码里的datetime.now()换成对应的时间即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:30:02