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

TimeSpan.ParseExact解析超59秒/分的自定义格式时间有何解决方案?

解决方案

最优的实现方案是将用户自定义格式动态转换为正则表达式,匹配提取各时间单位数值后累加计算总时长,完全适配动态可变的格式需求,不需要硬编码拆分规则。

实现逻辑

  1. 预定义时间单位和毫秒的换算关系,同时适配毫秒位的不同位数规则
  2. 遍历用户配置的时间格式字符串,生成对应的匹配正则,同时记录每个捕获组对应的单位信息:
    • 连续的d/h/m/s/f字符替换为(\d+)捕获组,记录单位类型和连续长度(用于毫秒位换算)
    • 非时间单位的字面量字符(包括转义后的分隔符、自定义文本)做正则转义后保留
  3. 用户输入内容用生成的正则匹配,依次取出每个捕获组的数值,乘以对应单位的换算值累加得到总毫秒数

示例代码

using System.Text.RegularExpressions;

public static class DynamicTimeParser
{
    // 时间单位对应的毫秒换算系数
    private static readonly Dictionary<char, long> _unitBaseMs = new()
    {
        {'d', 86400000 }, // 天
        {'h', 3600000 },  // 小时
        {'m', 60000 },    // 分钟
        {'s', 1000 },     // 秒
        {'f', 1 }         // 毫秒
    };

    public static bool TryParse(string input, string format, out long totalMs)
    {
        totalMs = 0;
        var regexPattern = "";
        var captureUnits = new List<(char unit, int length)>();
        int i = 0;
        while (i < format.Length)
        {
            char c = format[i];
            // 处理转义字符
            if (c == '\\')
            {
                regexPattern += Regex.Escape(format[i+1].ToString());
                i += 2;
                continue;
            }
            // 识别连续的时间单位符
            if (_unitBaseMs.ContainsKey(c))
            {
                int len = 1;
                while (i + len < format.Length && format[i+len] == c)
                    len++;
                regexPattern += @"(\d+)";
                captureUnits.Add((c, len));
                i += len;
                continue;
            }
            // 普通字面量转义
            regexPattern += Regex.Escape(c.ToString());
            i++;
        }
        // 完整匹配正则
        var regex = new Regex($"^{regexPattern}$");
        var match = regex.Match(input);
        if (!match.Success) return false;
        // 累加计算总毫秒
        for (int j = 0; j < captureUnits.Count; j++)
        {
            var (unit, len) = captureUnits[j];
            if (!long.TryParse(match.Groups[j+1].Value, out long val))
                return false;
            long ms = val * _unitBaseMs[unit];
            // 处理毫秒位不足3位的情况
            if (unit == 'f')
                ms *= (long)Math.Pow(10, 3 - len);
            totalMs += ms;
        }
        return true;
    }
}

调用方法

直接替换你原有代码中的TryParseTime方法即可:

static bool TryParseTime(string time, string format, out long parsed)
{
    return DynamicTimeParser.TryParse(time, format, out parsed);
}

方案优势

  • 完全兼容你现有支持的所有自定义格式,包括带自定义文本的格式如ss\s\. fff mils\.
  • 所有单位的数值都支持超过进位阈值(比如90分钟、100秒都可以正常解析)
  • 不需要依赖第三方库,纯原生实现,性能稳定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 08:45:05