为什么 "DateTime.Now.ToString("hh tt", new CultureInfo("de"))" return 在不同版本的 .Net 中有不同的结果?
Why does "DateTime.Now.ToString("hh tt", new CultureInfo("de"))" return different results in different versions of .Net?
我很困惑。在读到 this answer 我们应该依赖内置本地化后,我对以下观察结果感到惊讶:
当我运行
using System;
using System.Globalization;
public class Program
{
public static void Main()
{
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
}
}
根据框架 and/or 编译器,我得到的结果非常不同。示例基于 10:00 UTC(上午 10 点)。
- 运行 它在 try-dotnet 我得到:
10 vorm.
- 运行 它在 dotnetfiddle 上,“编译器”设置为 .NET 5 我得到相同的结果:
10 vorm.
现在是有趣的部分:
- 运行 它在 dotnetfiddle 上,“编译器”设置为 .NET 4.7.2 我得到:
10
- 运行 它在 dotnetfiddle 上,“编译器”设置为 Roslyn 我得到:
10
它变得更奇怪了:我已经在本地使用控制台应用程序进行了尝试,并将示例扩展为
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de-DE")));
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("fr")));
这些是结果 - 添加了 try-dotnet 以进行比较。
Culture
.NET 5
.NET Core 3.1
.NET Core 2.0
.NET Framework 4.8
Mono
try-dotnet
"de"
10 AM
10
10
10
10 vorm.
10 vorm.
"de-DE"
10
10
10
10
10 vorm.
10 vorm.
"fr"
10 AM
10
10
10
10 AM
10 AM
在 Mono 列中,结果来自使用 Mono 编译文件(Mono JIT 编译器版本 6.4.0),然后使用 Mono 运行编译它。 运行 没有 Mono 的 .exe 产生与第三列相同的结果。
这是从哪里来的,是编译器还是框架中的错误?它只是坏了还是故意设计的?
此重大更改是 the use of the ICU Libraries on Windows instead of the NLS Libraries 的结果。
您可以在 .net 5.0 应用程序中验证这一点,方法是将以下内容添加到项目中以从使用 ICU 库恢复为使用 NLS 库:
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>
在使用代码
将其添加到我的测试 .Net 5.0 控制台应用程序之后
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
输出从 11 AM
变为 11
(在撰写本文时)。
我很困惑。在读到 this answer 我们应该依赖内置本地化后,我对以下观察结果感到惊讶:
当我运行
using System;
using System.Globalization;
public class Program
{
public static void Main()
{
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
}
}
根据框架 and/or 编译器,我得到的结果非常不同。示例基于 10:00 UTC(上午 10 点)。
- 运行 它在 try-dotnet 我得到:
10 vorm.
- 运行 它在 dotnetfiddle 上,“编译器”设置为 .NET 5 我得到相同的结果:
10 vorm.
现在是有趣的部分:
- 运行 它在 dotnetfiddle 上,“编译器”设置为 .NET 4.7.2 我得到:
10
- 运行 它在 dotnetfiddle 上,“编译器”设置为 Roslyn 我得到:
10
它变得更奇怪了:我已经在本地使用控制台应用程序进行了尝试,并将示例扩展为
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de-DE")));
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("fr")));
这些是结果 - 添加了 try-dotnet 以进行比较。
Culture | .NET 5 | .NET Core 3.1 | .NET Core 2.0 | .NET Framework 4.8 | Mono | try-dotnet |
---|---|---|---|---|---|---|
"de" | 10 AM | 10 | 10 | 10 | 10 vorm. | 10 vorm. |
"de-DE" | 10 | 10 | 10 | 10 | 10 vorm. | 10 vorm. |
"fr" | 10 AM | 10 | 10 | 10 | 10 AM | 10 AM |
在 Mono 列中,结果来自使用 Mono 编译文件(Mono JIT 编译器版本 6.4.0),然后使用 Mono 运行编译它。 运行 没有 Mono 的 .exe 产生与第三列相同的结果。
这是从哪里来的,是编译器还是框架中的错误?它只是坏了还是故意设计的?
此重大更改是 the use of the ICU Libraries on Windows instead of the NLS Libraries 的结果。
您可以在 .net 5.0 应用程序中验证这一点,方法是将以下内容添加到项目中以从使用 ICU 库恢复为使用 NLS 库:
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>
在使用代码
将其添加到我的测试 .Net 5.0 控制台应用程序之后Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
输出从 11 AM
变为 11
(在撰写本文时)。