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

DateTime.ParseExact转换失败:单数字小时引发无效日期时间错误

解决DateTime.ParseExact解析单小时位时间字符串的错误

问题描述

String was not recognized as a valid DateTime. stack: at System.DateTimeParse.ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style)

发现仅当尝试将以单个0开头的时间字符串转换为DateTime时才会触发该错误。现有读取日志文件的脚本,需要判断日期是否在指定范围内,但日志行数过多,不想用正则表达式逐行检查小时部分的格式,也不愿修改日志或日志生成逻辑,求正确转换此类字符串的方法。

相关代码

string serverPath = @"\\" + serverName;
string logNameFull = logName + ".txt";
string partialPath = @"\build\logs\";
string combinedPath2 = partialPath + logNameFull;
Uri serverUri = new Uri(serverPath + combinedPath2);
string finalPath = serverUri.LocalPath;
DataTable dataTable = ReadDataTable(finalPath);

foreach (DataRow row in dataTable.Rows)
{
    try
    {
        if (Regex.IsMatch((row[startTimeHeader]).ToString(), @"^\d+")) //过滤非日期格式的日志行
        {
            string tmpStartDT = (row[startTimeHeader]).ToString();
            startDate = DateTime.ParseExact(tmpStartDT, "MM/dd/yyyy HH:mm:ss", provider); //出错行
        }
   }
   catch (Exception ex)
   {
      Console.WriteLine("Caught exception for  row: {0} CName:{1} on line close to:{2} server:{3} logname:{4} startDate:{5}", row.ToString(), cName, debug_i, serverName, logName, row[startTimeHeader]);
      Console.WriteLine("Message: " + ex.Message + " stack:" + ex.StackTrace);
   }
}  // foreach

控制台错误输出

Caught exception for row: System.Data.DataRow CName:CopyLogFile on line close to:475 server:mach62 logname:ParseLogStats startDate:04/14/2024 0:38:07

对应日志行内容

04/14/2024  0:38:07 04/14/2024  0:38:13 Sun 00:00:06    6   Success v24.1 Incr Stage_M  0   967 0   0   0   0   0   0   0   I:\logs\Stage_.log  
Message: String was not recognized as a valid DateTime. stack:   at System.DateTimeParse.ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style)
   at System.DateTime.ParseExact(String s, String format, IFormatProvider provider)
   at BuildStatusVerification.BuildStatusVerification.ParseLogFile(String codeFreezeTime, String startTimeHeader, String serverName, String logName, String cName, String cValue, String field1, String comparison1, String val) in C:\BuildStatusVerification\BuildStatusVerification\BuildStatusVerification.cs:line 150

解决方案

核心问题是格式字符串"MM/dd/yyyy HH:mm:ss"要求小时为两位数字(HH是24小时制的两位格式),但日志中的小时是一位(比如0:38:07),同时日期和小时之间存在两个空格。解决方法是传入多个可能的格式字符串,让ParseExact自动尝试匹配任意一种:

修改出错行的代码为:

// 同时支持两位小时和一位小时的格式,注意空格数量对应日志格式
string[] formats = { "MM/dd/yyyy HH:mm:ss", "MM/dd/yyyy  H:mm:ss" };
startDate = DateTime.ParseExact(tmpStartDT, formats, provider, DateTimeStyles.None);

说明

  • HH对应两位小时(00-23),H对应一位或两位小时(0-23)
  • 第二个格式中的 H(两个空格)对应日志中日期与小时之间的两个空格
  • 使用ParseExact的多格式重载,无需逐行预处理或修改日志,直接适配两种时间格式

这样就能同时解析正常两位小时和单小时位的时间字符串,满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:56:08