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

如何计算SQL中工单/呼叫的解决耗时?C#应用周末不计时需求咨询

嘿,这两个问题我刚好有不少实践经验,来给你拆解一下:

1. 从SQL数据库获取工单解决耗时

首先得确认你的工单表有没有存储受理时间(比如accept_time)和解决时间(比如resolve_time)这两个核心字段——没有的话得先补上,不然没法计算。接下来分两种场景:

场景1:只需要总耗时(包含周末)

如果不需要排除周末,直接用SQL的时间差函数就行,不同数据库写法略有不同:

  • SQL Server:SELECT DATEDIFF(MINUTE, accept_time, resolve_time) AS total_duration_minutes FROM work_orders;
  • MySQL:SELECT TIMESTAMPDIFF(MINUTE, accept_time, resolve_time) AS total_duration_minutes FROM work_orders;
  • PostgreSQL:SELECT EXTRACT(EPOCH FROM (resolve_time - accept_time)) / 60 AS total_duration_minutes FROM work_orders;

场景2:需要排除周末的有效耗时

这就麻烦点,得计算两个时间点之间的工作日时长。这里给你几个主流数据库的实现思路:

  • SQL Server:可以写一个自定义函数,或者用CTE生成两个时间点之间的所有日期,过滤掉周六周日,再计算每个工作日的有效时长(比如跨天的话,第一天算从受理时间到当天结束,最后一天算从当天开始到解决时间,中间的工作日算全天)。示例片段:
WITH date_range AS (
    SELECT DATEADD(DAY, number, CAST(accept_time AS DATE)) AS work_day
    FROM master.dbo.spt_values
    WHERE type = 'P'
    AND number BETWEEN 0 AND DATEDIFF(DAY, accept_time, resolve_time)
)
SELECT SUM(
    CASE
        WHEN work_day = CAST(accept_time AS DATE) THEN DATEDIFF(MINUTE, accept_time, DATEADD(DAY, 1, CAST(accept_time AS DATE)))
        WHEN work_day = CAST(resolve_time AS DATE) THEN DATEDIFF(MINUTE, CAST(resolve_time AS DATE), resolve_time)
        ELSE 1440 -- 全天1440分钟
    END
) AS work_duration_minutes
FROM date_range
WHERE DATEPART(WEEKDAY, work_day) NOT IN (1,7); -- 假设周日是1,周六是7,根据你的SQL Server设置调整
  • MySQL:可以用存储过程或者自定义函数,循环遍历日期排除周末,计算累计时长。或者用generate_series(MySQL 8.0+支持)生成日期范围再过滤。
  • PostgreSQL:利用generate_series生成时间范围内的所有日期,结合EXTRACT(DOW FROM work_day)排除周六(6)和周日(0),再计算时长。
2. C#应用中跟踪呼叫受理到解决的耗时(排除周末)

其实不需要实时跑计时器——因为受理和解决都是触发式事件,你只需要在受理时记录当前时间,解决时记录当前时间,之后再用这两个时间点计算有效耗时就行。具体实现思路:

步骤1:数据存储设计

在你的呼叫记录模型里,添加两个DateTimeOffset(推荐用这个避免时区问题)字段:

  • AcceptedAt:受理时的时间(存UTC时间,比如DateTimeOffset.UtcNow)
  • ResolvedAt:解决时的时间

步骤2:计算有效耗时的工具方法

写一个静态工具类,实现计算两个时间点之间排除周末的时长。这里给你一个简单清晰的实现:

public static class WorkDurationCalculator
{
    public static TimeSpan CalculateWorkDuration(DateTimeOffset start, DateTimeOffset end)
    {
        if (start >= end)
            return TimeSpan.Zero;

        TimeSpan totalDuration = TimeSpan.Zero;
        DateTimeOffset currentDay = start.Date;

        while (currentDay <= end.Date)
        {
            // 排除周六和周日
            if (currentDay.DayOfWeek != DayOfWeek.Saturday && currentDay.DayOfWeek != DayOfWeek.Sunday)
            {
                DateTimeOffset dayStart = currentDay;
                DateTimeOffset dayEnd = currentDay.AddDays(1);

                // 处理第一天:从start到当天结束
                if (currentDay == start.Date)
                    dayStart = start;

                // 处理最后一天:从当天开始到end
                if (currentDay == end.Date)
                    dayEnd = end;

                totalDuration += dayEnd - dayStart;
            }

            currentDay = currentDay.AddDays(1);
        }

        return totalDuration;
    }
}

如果时间跨度很大需要更高效计算,可以用数学公式:先算总天数,减去周末天数,再乘以每天时长,最后调整首尾两天的部分时间——不过上面的方法对大多数场景已经足够清晰好用。

步骤3:业务逻辑触发

  • 当用户提交呼叫并被受理时,记录AcceptedAt = DateTimeOffset.UtcNow;
  • 当呼叫被标记为解决时,记录ResolvedAt = DateTimeOffset.UtcNow;
  • 需要展示耗时的时候,调用WorkDurationCalculator.CalculateWorkDuration(acceptedAt, resolvedAt),再转换成小时/分钟展示给用户。

另外注意时区转换:如果用户在不同时区,展示时把UTC时间转成用户本地时间,但计算耗时务必用UTC时间避免误差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:18:58