C# 为什么对DateTime.TryParseExact的调用会因输入而失败;1212012“;使用格式字符串";Mddyyyy“;

C# 为什么对DateTime.TryParseExact的调用会因输入而失败;1212012“;使用格式字符串";Mddyyyy“;,c#,.net,C#,.net,我有一个日期字符串,我认为它是Mddyyyy。然而,TryParseExact似乎不起作用。以下是失败的示例代码: string datestring = "1212012"; DateTime td; if (DateTime.TryParseExact(datestring, "Mddyyyy", new CultureInfo("en-US"), DateTimeStyles.None, out td)) { Console.WriteLine(td.ToShortDat

我有一个日期字符串,我认为它是Mddyyyy。然而,TryParseExact似乎不起作用。以下是失败的示例代码:

string datestring = "1212012";

DateTime td;
if (DateTime.TryParseExact(datestring, "Mddyyyy", new CultureInfo("en-US"),     DateTimeStyles.None, out td))
{
    Console.WriteLine(td.ToShortDateString());
}
else
{
    Console.WriteLine("Invalid Date String");
}

如果有前导零,同样的代码也可以工作,但我认为前导零只能与格式字符串MMddyyyy一起工作。

这里我提出一个解释并为该建议提供证据

建议的解释:解析器在内部使用格式字符串创建包含贪婪量词的正则表达式(这意味着,在本例中,它更喜欢匹配2位月份而不是1位月份)。OP格式字符串中的
M
在解析器的内部正则表达式中类似于
\d{1,2}
(尽管这将匹配编号为0到99之间的月份!)

证据:如果将月份移动到数据和格式字符串的末尾,贪婪量词不能获得超过1位的数字,因此它会根据需要匹配月份:

string datestring = "2120121";

DateTime td;
if (DateTime.TryParseExact(datestring, "ddyyyyM", new CultureInfo("en-US"), DateTimeStyles.None, out td))
{
    Console.WriteLine(td.ToShortDateString());
}
else
{
    Console.WriteLine("Invalid Date String");
}

底线:不要依赖未记录的行为。始终使用明确的数据,即两位数的月份。

提示:您的示例日期是2012年1月21日还是2012年12月1日?另外,我们也很欣赏你帖子中的实际问题(尽管我认为可以假设你在问“我如何让TryParseExact解析这个日期?”),我看到了歧义,但这是否意味着1月份的日期在10-29天范围内,如果以Mddyyyy格式给出,则无法通过DateTime解析?我知道你不应该用这种格式来表示日期,但我很好奇,很可能是的。你可以用零填充左边来解决这个问题。可能的原因是TryParseExact使用的解析器或正则表达式的结构。前导的M表示指定月份的初始数字的可变数量,并且只有通过查看字符串的总长度才能知道正确的决策路径。我敢打赌解析器并没有那么复杂,尽管我承认我还没有看过。如果人类不能确定那可能是什么日期,那么可以安全地假设机器也不能。但是,是的,你可以自己编写自定义解析器来发现这一点。类似的问题:我终于有机会研究解析代码本身——虽然这不是一个精确的答案(因为实际上没有使用正则表达式),但它在功能上是准确的,我同意底线。是的,IL。使用reflector,您可以将其视为与原始C语言类似的东西#