DateTime.TryParseExact未按预期工作

任何人都可以解释为什么以下片段返回true?

根据“d”自定义格式说明符的文档,“一位数字日的格式没有前导零”。 那么,为什么当我给一个前导零的一位数日时,TryParseExact不会失败?

DateTime x; return DateTime.TryParseExact ( "01/01/2001", @"d\/MM\/yyyy", null, System.Globalization.DateTimeStyles.None, out x ); 

UPDATE

我想也许我原本不清楚。 我真正想要的是: 为什么TryParseExact接受一些不完全匹配的值? 从我看到的所有文档中,’d’匹配’01’和’1’就像’MM’匹配’March’和’03’一样。 这里的问题不是值是等价的,它们与格式不匹配。

相关的文档片段是:

  • 来自TryParseExact : 字符串表示的格式必须与指定的格式完全匹配。

  • 来自’d’说明符 : 一位数字日的格式没有前导零。

我似乎非常清楚’01’有一个前导0,因此不完全匹配’d’。

来自DateTimeParse.ParseByFormat()中的.NET 4源代码:

 case 'd': // Day & Day of week tokenLen = format.GetRepeatCount(); if (tokenLen <= 2) { // "d" & "dd" if (!ParseDigits(ref str, tokenLen, out tempDay)) { if (!parseInfo.fCustomNumberParser || !parseInfo.parseNumberDelegate(ref str, tokenLen, out tempDay)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } if (!CheckNewValue(ref result.Day, tempDay, ch, ref result)) { return (false); } } else {...} 

解析器将“d”和“dd”整合在一起。

行为似乎是设计的,我认为它的工作方式与其他字符串格式化选项一致。

采用以下示例:

 //Convert DateTime to string string dateFormat = "d/MM/yyyy"; string date1 = new DateTime(2008, 10, 5).ToString(dateFormat); string date2 = new DateTime(2008, 10, 12).ToString(dateFormat); //Convert back to DateTime DateTime x1, x2; DateTime.TryParseExact(date1, dateFormat, null, System.Globalization.DateTimeStyles.None, out x1); DateTime.TryParseExact(date2, dateFormat, null, System.Globalization.DateTimeStyles.None, out x2); Console.WriteLine(x1); Console.WriteLine(x2); 

在第一部分中, ToString()输出10月12日的两位数日,因为仅写出一个数字日(以及它将选择哪个数字,1或2?)没有多大意义。 因此,当转换为字符串时,“d”表示一个或两个数字天,在转换回DateTime时,它必须以相同的方式工作。 如果没有,在我的示例中,在TryParseExact中转换回DateTime会失败,这肯定不是预期的行为。

我会说,如果你真的需要完全匹配ad / MM / yyyy格式,你可以使用正则表达式来validation字符串,然后通过ParseTryParseTryParseExact传递它(取决于你的正则表达式有多好,因为它会必须处理闰年,30/31天等,如果你想使用Parse )。

我会说它没有失败,因为TryParseExact非常聪明,知道’01’==’1’。

我想, TryParseExact只是试图在这种情况下灵活。 但是,当您使用格式说明符将日期转换为字符串时,“d”与“dd”应当并且将按照广告的方式工作。

因为单个’d’表示您的DateTime值将被转换为尽可能短的值,即如果没有必要,则不会导致零。 我认为当你从字符串转换为DateTime时它不应该失败,因为TryParseExact的格式字符串的主要目的是帮助转换为DateTime,即它像提示一样 ,它不打算validation字符串格式。

如果仍需要硬核字符串格式validation,则可以使用RegEx 。