DateTime.TryParseExact未按预期工作

时间:2011-05-06 00:52:57

标签: c# datetime tryparse

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

根据The "d" custom format specifier的文档,“一位数字日的格式没有前导零。”那么,为什么当我给一个前导零的一位数日时,TryParseExact不会失败?

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

更新

我想也许我原本不清楚。我真正想要的是:为什么TryParseExact接受一些不完全匹配的值?来自我看过的所有文档,'d'匹配'01'和'1'就像'MM'匹配'March'和'03'一样,也是一个错误。 这里的问题不是价值相等,而是与格式不符。

相关的文档摘要如下:

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

  • 来自The 'd' Specifier一位数字日的格式没有前导零。

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

5 个答案:

答案 0 :(得分:8)

来自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”整合在一起。

答案 1 :(得分:3)

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

采用以下示例:

//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时,它必须以相同的方式工作。如果没有,在我的示例中转换回DateTime中的TryParseExact会失败,这肯定不是预期的行为。

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

答案 2 :(得分:0)

在我猜这种情况下,

TryParseExact正试图变得灵活。但是,当您使用格式说明符将日期转换为字符串时,“d”与“dd”应该并且将会像宣传的那样工作。

答案 3 :(得分:0)

我会说它没有失败,因为TryParseExact足够聪明,知道'01'=='1'。

答案 4 :(得分:0)

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

如果您仍需要核心字符串格式验证,则可以使用RegEx