繁体   English   中英

DateTime.TryParseExact未按预期工作

[英]DateTime.TryParseExact not working as expected

任何人都可以解释为什么以下片段返回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格式,你可以使用正则表达式验证字符串,然后通过ParseTryParseTryParseExact传递它(取决于你的正则表达式有多好,因为它会必须处理闰年,30/31天等,如果你想使用Parse )。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM