您的情况看起来像另一个最广泛的形式问题。
来自DateTime.TryParseExact method
如果您不在自定义格式模式中使用日期或时间分隔符,
对提供者参数使用不变的文化和最广泛的
每个自定义格式说明符的形式。例如,如果你想
在模式中指定小时,指定更宽的形式,“HH”,而不是
更窄的形式,“H”。
因此,有时解析没有任何日期或时间分隔符的字符串可能会出现问题。
例如让我们谈谈"d" custom format specifier。对于格式化部分,它会使用单个数字 格式化您的一天部分。但是对于解析,它可以同时解析4 和04。与"M" custom format specifier 相同。我不是说你应该使用d 说明符来表示04。你可以,但你不应该。您应该始终使用最适合您的字符串的最佳格式。
这是我对这里发生的事情的看法;
由于 最宽形式 规则,由于您的字符串没有任何日期分隔符,因此您的格式应该期望d 和M 的最宽形式,它们是dd 和MM。但我认为这些说明符在用于单个数字时希望 带有 前导零值(例如:06 和 04),因为它们的实际用途。我找不到任何证据来支持我的理论,但我仍在调查它。
如果您的字符串总是 Mdyyyy 格式,我有一个解决方案。也许这不是最好的解决方案,但我认为如果您的字符串具有恒定格式,它会很有用;
public static DateTime? ParseDate_Mdyyyy(string date)
{
if (date == null)
return null;
if (date.Length < 6)
return null;
if (date.Length == 6)
date = date.Insert(0, "0").Insert(2, "0");
DateTime dt;
if (DateTime.TryParseExact(date, "MMddyyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
return dt;
return null;
}
现在你可以用这个方法了;
string s = "642014";
DateTime? date = ParseDate_Mdyyyy(s);
Console.WriteLine(date.Value.ToString("ddMMyyyy")); // 04062014
我就这个问题与 .NET Framework 团队联系过,他们的回应是;
嗨,Soner,
解析代码并没有真正寻找任何分隔符。这是什么
正在进行中:
对于使用“MMddyyyy”的情况,在方法中开始解析
DoStrictParse 将调用 ParseByFormat。该方法将获得
格式的第一部分是“MM”,然后调用ParseDigits
从我们解析的字符串中获取等效数字 “642014” 这将
给“64”。 请注意,在此之前没有验证发生,如果
该数字超出所选日历中月份的范围
(在我们这里是公历)。解析代码会重复
“dd” 的相同过程将得到等效部分 “20” 然后
将为“yyyy” 重复它,但这会失败,因为它期望4 数字和
我们只有两个 (“14”)。
对于使用“Mdyyyy”的情况,它失败了,因为几乎相同的原因
在解析 “M” 部分时,我们知道月份可以是 2 数字所以
我们将其映射到“64” 并将对“d” 执行相同的操作,将其映射到“20”
然后一年将失败。我相信这就是原因
文档说总是使用最宽的形式。
这里的建议是要么使用2 数字形式
像"06042014" 这样的字符串,解析应该成功“MMddyyyy”
还有“Mdyyyy”。其他选项是插入分隔符"6/4/2014" 或
"06/04/2014" 并解析为"M/d/yyyy"
谢谢,塔雷克
特别感谢; Tarek Mahmoud Sayed、Wes Haggard 和 Richard Lander。