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

解析DateTime时触发System.ArgumentOutOfRangeException:Length不能小于0

解析DataGrid日期时间列时的DateTime.Parse异常问题

问题场景

要解析DataGrid中某列的日期时间数据,该列格式示例如下:

3:44 PM 22/02/2023 
10:58 PM 17/02/2023

通过Debug.WriteLine测试,提取时间部分的代码看似正常,但调用DateTime.Parse时抛出异常:

System.ArgumentOutOfRangeException: 'Length cannot be less than zero. Arg_ParamName_Name'

原代码如下:

string dateText = trade.Date.ToString();

int indexM = dateText.IndexOf('M');

if (indexM >= 0) // Check if 'M' exists in the string
{
    dateText = dateText.Substring(0, indexM + 1); // Include the 'M'
}

DateTime time = DateTime.Parse(dateText);

问题分析

  1. 文化设置不兼容:如果当前系统线程的文化不是英文体系,DateTime.Parse默认无法识别AM/PM格式的时间字符串,会导致解析失败甚至抛出异常。
  2. 字符串提取逻辑隐患:仅通过IndexOf('M')提取时间的方式不够健壮,若trade.Date.ToString()返回的字符串格式异常(比如多个M字符、M出现在非AM/PM位置),会导致提取的时间字符串格式无效。
  3. 空值/无效字符串未处理:若trade.Date.ToString()返回空字符串或空白字符串,后续操作可能触发异常。

解决方案

方案1:指定文化信息解析

如果提取的时间字符串是XX:XX AM/PM格式,直接指定InvariantCulture即可让DateTime.Parse正确识别:

string dateText = trade.Date.ToString().Trim();

int indexM = dateText.IndexOf('M');
if (indexM >= 0)
{
    dateText = dateText.Substring(0, indexM + 1).Trim();
}

// 指定不变文化,确保识别AM/PM格式
DateTime time = DateTime.Parse(dateText, CultureInfo.InvariantCulture);

方案2:更健壮的时间提取+TryParse安全解析

通过分割字符串提取时间部分,并用DateTime.TryParse避免抛出异常:

string rawDateText = trade.Date.ToString().Trim();
if (string.IsNullOrWhiteSpace(rawDateText))
{
    // 处理空值或无效字符串,比如返回默认值或抛出明确异常
    throw new InvalidOperationException("日期字符串为空或格式无效");
}

// 按空格分割,取前两部分(时间+AM/PM)
string[] parts = rawDateText.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length >= 2)
{
    string timeText = $"{parts[0]} {parts[1]}";
    if (DateTime.TryParse(timeText, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime time))
    {
        // 解析成功,使用time变量
    }
    else
    {
        // 解析失败,添加自定义处理逻辑
    }
}
else
{
    // 字符串格式不符合预期,添加处理逻辑
}

方案3:使用ParseExact精准匹配格式

如果确定时间部分的格式固定为h:mm tt(12小时制+AM/PM),可以用ParseExact直接匹配,避免歧义:

string rawDateText = trade.Date.ToString().Trim();
// 提取包含AM/PM的前半段时间
int ttEndIndex = rawDateText.IndexOf('M') + 1;
if (ttEndIndex > 0 && ttEndIndex <= rawDateText.Length)
{
    string timeText = rawDateText.Substring(0, ttEndIndex).Trim();
    DateTime time = DateTime.ParseExact(timeText, "h:mm tt", CultureInfo.InvariantCulture);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:16:05