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工作的。

它有五个重载,但我们只讨论它们都重定向到的一个(这不是实际代码,如果您想使用 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值。如果您使用的是字符串,则格式将被忽略,因为只有一种方法可以输出字符串。

于 2012-07-25T21:45:33.843 回答
2

因为“05-22-2012”不是IFormattableDateTime.Parse("05-22-2012")它是DateTime

请在此处查看更多示例

于 2012-07-25T21:51:29.150 回答