1

ちょっと興味があります...したがって、日付の文字列バージョンを DateTime オブジェクトに変換して String.Format() メソッドに渡すと、目的の結果が得られることがわかります。

String.Format("The date is {0:MMMM dd, yyyy}", DateTime.Parse("05-22-2012"));

「日付は 2012 年 5 月 22 日です」

しかし、なぜこれが機能しないのでしょうか。

String.Format("The date is {0:MMMM dd, yyyy}", "05-22-2012")

「日付は 2012 年 5 月 22 日です」

これがばかげた質問である場合は申し訳ありませんが、これがどのように機能するかを理解しようとしています。ありがとう

4

3 に答える 3

3

ここでの他の答えは重要なポイントに当てはまりますが、それらをすべてまとめて、どのようにString.Format機能するかを調べてみましょう。

5つのオーバーロードがありますが、すべてがリダイレクトされるものについてのみ説明します(これは実際のコードではありません。ReflectorまたはILSpyで表示する場合は、にありますStringBuilder.AppendFormat)。これは、理解しやすいように簡略化されています。

public static string Format(IFormatProvider provider, string format, params object[] args)
{
    StringBuilder sb = new StringBuilder();

    // Break up the format string into an array of tokens
    Token[] tokens = ParseFormatString(format);

    foreach (Token token in tokens)
    {
        switch (token.TokenType)
        {
            // A Text token is just some text to output directly
            case TokenType.Text:
                sb.Append(token.Text);
                break;

            // An Index token represents something like {0} or {2:format}
            //  token.Index is the argument index
            //  token.FormatText is the format string inside ('' in the first example, 'format' in the second example)
            case TokenType.Index:
                {
                    object arg = args[token.Index];

                    IFormattable formattable = arg as IFormattable;
                    if (formattable != null && token.FormatText.Length > 0)
                    {
                        // If the argument is IFormattable we pass it the format string specified with the index
                        sb.Append(formattable.ToString(token.FormatText, provider));
                    }
                    else
                    {
                        // Otherwise we just use Object.ToString
                        sb.Append(arg.ToString());
                    }
                }
                break;
        }
    }

    return sb.ToString();
}

あなたの質問では、「05-22-2012」を渡したときにフォーマット文字列が適用されない理由を尋ねます。Guffaが言ったように、それはDateTimeオブジェクトではなく、Stringオブジェクトです。

GSerjoが言ったように、文字列はIFormattableではありません。書式設定は何かを文字列に変換するプロセスであるため、文字列は書式設定できません。文字列はすでに文字列です!

したがって、Formatメソッドがインデクサーにarg到達すると、IFormattableではなくなり、単に。を呼び出すことがわかりますToString。文字列に対してToStringを呼び出すと、それ自体が返されます。これはすでに文字列です。

要約すると、フォーマット文字列に内部フォーマット文字列({0:format}など)のインデックスが含まれている場合、その内部フォーマット文字列は、関連付けられた引数がIFormattableであり、フォーマット文字列の処理方法を認識している場合にのみ適用されます。それを与える。

于 2012-07-25T22:30:32.800 に答える
2

カスタム日時形式は、DateTime値に対してのみ機能します。代わりに文字列を使用している場合、文字列を出力する方法は1つしかないため、形式は無視されます。

于 2012-07-25T21:45:33.843 に答える
2

「2012 年 5 月 22 日」はではないためIFormattableDateTime.Parse("05-22-2012")DateTime

その他の例については、こちらをご覧ください

于 2012-07-25T21:51:29.150 に答える