解释日期:Console.Writeline与string.Format [英] Interpreting dates: Console.Writeline vs. string.Format
问题描述
给出以下C#代码:
var dt = DateTime.Now;
Console.WriteLine("{0:MM/dd/yy} ... {1}", dt, string.Format("{0:MM/dd/yy}", dt));
...当短日期时(在Windows 7下,控制面板- >区域和语言->其他设置->日期
)设置为美国标准 M / d / yyyy
我明白了:
... when the short date (under Windows 7, Control Panel -> Region and Language -> Additonal Settings -> Date
) is set to the USA standard of "M/d/yyyy
," I get this:
06/17/14 ... 06/17/14
但是,当我将短日期更改为 ddd dd MMM yyyy
时,我得到这个:
However, when I change the short date to "ddd dd MMM yyyy
," I get this:
06/17/14 ... 06 17 14
我的印象是 Console.WriteLine
和 string.Format
始终将字符串格式的 DateTime
值相同。这种差异的解释是什么?
I was under the impression that Console.WriteLine
and string.Format
always string formatted DateTime
values identically. What is the explanation for this discrepancy?
编辑:看起来这仅发生在标准单元测试输出(Visual Studio)中我最初看到了问题。在控制台应用程序中执行代码时,输出为 06 17 14 ... 06 17 14
。
Looks like this happens only in standard unit test output (Visual Studio), which is where I originally saw the problem. When the code executes in a console app, the output is 06 17 14 ... 06 17 14
.
推荐答案
之所以会出现这种情况,是因为MSTest将控制台输出重定向到测试窗口时,它将 CultureInfo.InvariantCulture
传递给与控制台关联的TextWriter
。
This situation arises because when MSTest redirects console output to the test window, it passes CultureInfo.InvariantCulture
to the TextWriter
associated with the console.
您可以使用以下命令进行验证:
You can verify this with the following:
var threadCulture = Thread.CurrentThread.CurrentCulture;
var consoleCulture = Console.Out.FormatProvider;
Console.WriteLine(threadCulture.Equals(CultureInfo.InvariantCulture));
Console.WriteLine(consoleCulture.Equals(CultureInfo.InvariantCulture));
除非您进行更改,否则线程的当前文化通常类似于 en-美国
,或您的计算机设置为的任何值。因此,第一项通常是错误的。
Unless you change it, the thread's current culture is usually something like en-US
, or whatever your computer is set to. So the first item will usually be false.
但是第二项根据其来源而有所不同。作为控制台应用程序,控制台输出区域性应默认为当前线程区域性-因此它将为false。在XUnit或NUnit测试中,结果也是假的。但是在MSTest中,结果为true。
But the second item varies depending on where it's run from. As a console application, the console output culture should default to the current thread culture - so it will be false. In XUnit or NUnit tests, the result is also false. But in MSTest, the result is true.
如果您浏览 .NET Framework参考源,您将看到
Out
是 TextWriter
和 TextWriter.WriteLine
使用为其分配的 FormatProvider
Out
is a TextWriter
, and TextWriter.WriteLine
uses its assigned FormatProvider
FormatProvider
是 null
以使用当前线程,或者是由构造函数参数分配。
我认为MSTest测试运行程序的来源不公开,但可以得出结论,他们必须在某个地方做类似的事情:
I don't think the sources for the MSTest test runner are publicly available, but one can conclude that they must somewhere do something like:
Console.Out = new SomeWriter(CultureInfo.InvariantCulture);
其中 SomeWriter
创建测试输出并继承来自 TextWriter
。
Where SomeWriter
creates the test output and inherits from TextWriter
.
另一方面, String.Format
将始终使用线程的当前区域性,除非您专门提供了不同的区域性。
On the other hand, String.Format
will always use the thread's current culture, unless you specifically provide a different culture.
一种解决方法是将线程的当前区域性显式设置为
One way to work around this would be to explicitly set the thread's current culture to the invariant culture.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
这篇关于解释日期:Console.Writeline与string.Format的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!