11

次のスニペットが true を返す理由を説明できる人はいますか?

The "d" custom format specifierのドキュメントによると、「1 桁の日は先行ゼロなしでフォーマットされます。」では、先頭に 0 を付けて 1 桁の日付を指定しても、TryParseExact が失敗しないのはなぜでしょうか?

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

アップデート

たぶん最初はわかりにくかったと思います。私が実際に取得しようとしているのは、TryParseExact が正確に一致しない値を受け入れるのはなぜですか? 私が見たすべてのドキュメントから、「d」が「01」と「1」に一致することは、「MM」が「3 月」と「03」に一致するのと同じくらいバグです。ここでの問題は、値が等しいということではなく、形式が一致しないということです。

関連するドキュメントのスニペットは次のとおりです。

  • TryParseExactから:文字列表現の形式は、指定された形式と正確に一致する必要があります。

  • 「d」指定子から: 1 桁の日は、先行ゼロなしでフォーマットされます。

「01」の先頭に 0 があるため、「d」と完全に一致しないことは明らかです。

4

5 に答える 5

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" をまとめて扱います。

于 2011-05-06T01:28:34.437 に答える
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 日の 2 桁の日を出力します。これは、1 桁の日を書き出すだけではあまり意味がないためです (そして、1 と 2 のどちらの数字が選ばれるのでしょうか?)。したがって、文字列に変換するとき、「d」は1 桁または 2DateTime桁の日を表すため、に戻す場合も同じように機能する必要があります。そうでない場合、私の例での in への変換DateTimeTryParseExact失敗し、それは間違いなく予期された動作ではありません。

ad/MM/yyyy 形式を正確に一致させる必要がある場合は、おそらく正規表現を使用して文字列を検証し、それをParseTryParseまたはTryParseExact(正規表現がどれだけ優れているかによって、処理する必要があるため) に渡すことができます。閏年、30/31 日などを使用したい場合Parse)。

于 2011-05-06T01:21:47.263 に答える
0

TryParseExactこの場合、柔軟になろうとしているだけだと思います。ただし、フォーマット指定子を使用して日付を文字列に変換する場合、「d」と「dd」は宣伝どおりに機能するはずです。

于 2011-05-06T00:58:50.373 に答える
0

TryParseExact'01' == '1' であることを十分に認識できるので、失敗することはないと思います。

于 2011-05-06T01:04:17.137 に答える
0

単一の 'd' は、DateTime 値ができるだけ短い値に変換されることを意味するためです。つまり、必要がない場合は先頭にゼロを付けません。TryParseExact のフォーマット文字列の主な目的は DateTime への変換を支援することであるため、文字列から DateTime に変換するときに失敗するべきではないと思います。つまり、ヒントのように機能し、文字列形式を検証することを意図していません。

それでもハードコアな文字列形式の検証が必要な場合は、 RegExを使用できます。

于 2011-05-06T01:22:42.857 に答える