Mil*_*oDC 6 .net c# string.format datetime console.writeline
给出以下C#代码:
var dt = DateTime.Now;
Console.WriteLine("{0:MM/dd/yy} ... {1}", dt, string.Format("{0:MM/dd/yy}", dt));
Run Code Online (Sandbox Code Playgroud)
...当短日期(在Windows 7下Control Panel -> Region and Language -> Additonal Settings -> Date)设置为美国标准" M/d/yyyy,"时,我得到:
06/17/14 ... 06/17/14
Run Code Online (Sandbox Code Playgroud)
但是,当我将短日期更改为" ddd dd MMM yyyy,"时,我得到了这个:
06/17/14 ... 06 17 14
Run Code Online (Sandbox Code Playgroud)
我的印象是,Console.WriteLine并且string.Format始终将字符串格式化的DateTime值相同.这种差异的解释是什么?
编辑:看起来这只发生在标准的单元测试输出(Visual Studio),这是我最初看到的问题.当代码在控制台应用程序中执行时,输出为06 17 14 ... 06 17 14.
出现这种情况的原因是,当 MSTest 将控制台输出重定向到测试窗口时,它会传递CultureInfo.InvariantCulture到TextWriter与控制台关联的窗口。
您可以通过以下方式验证这一点:
var threadCulture = Thread.CurrentThread.CurrentCulture;
var consoleCulture = Console.Out.FormatProvider;
Console.WriteLine(threadCulture.Equals(CultureInfo.InvariantCulture));
Console.WriteLine(consoleCulture.Equals(CultureInfo.InvariantCulture));
Run Code Online (Sandbox Code Playgroud)
除非您更改它,否则线程的当前区域性通常类似于en-US, 或您的计算机设置的任何内容。所以第一项通常是假的。
但第二项会根据其运行位置而有所不同。作为控制台应用程序,控制台输出区域性应默认为当前线程区域性 - 因此它将为 false。在 XUnit 或 NUnit 测试中,结果也是错误的。但在MSTest中,结果是正确的。
如果您仔细研究.NET Framework 参考源,您会发现
Out是 a TextWriter,并TextWriter.WriteLine使用其分配的FormatProvider
我认为 MSTest 测试运行程序的源代码不是公开的,但可以得出结论,它们必须在某处执行以下操作:
Console.Out = new SomeWriter(CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)
其中SomeWriter创建测试输出并继承自TextWriter.
另一方面,String.Format将始终使用线程的当前区域性,除非您专门提供不同的区域性。
解决此问题的一种方法是将线程的当前区域性显式设置为不变区域性。
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Run Code Online (Sandbox Code Playgroud)