解释日期:Console.Writeline与string.Format [英] Interpreting dates: Console.Writeline vs. string.Format

查看:90
本文介绍了解释日期:Console.Writeline与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆