<decimal>.ToString("P3") returns Win7 和 Windows 10 上的不同结果
<decimal>.ToString("P3") returns differerent results on Win7 and Windows 10
我有两个盒子:一个 Win7 和另一个 Win10(还有一个 Windows Server 2012 盒子,它的行为与我的 Win10 盒子相同)。
所有盒子上都安装了 .NET 版本 4.5.2。
当我运行以下代码时:
Dim d As Decimal = 1.23
Console.WriteLine((d / 100D).ToString("P3"))
然后我在 Win7 上得到这个结果:
1,230%
在 Win 10 和 Windows Server 2012 上我得到了这个结果:
1,230 %
注意百分号前的 space。
谁能帮我看看为什么会这样?我仔细检查了.NET版本,它们都是4.5.2,所以这可能与操作系统有关吗?
非常感谢大家。
更新:
使用
Console.WriteLine((d / 100D).ToString("P3", CultureInfo.InvariantCulture))
我在所有机器上都得到了这个结果:
1,230 %
但是当输出
Console.WriteLine(Thread.CurrentThread.CurrentCulture.Name)
在我得到的所有机器上
de-DE
我原以为文化一定会表现出不同的东西,因为会产生不同的结果,但由于一切都是去德的,我仍然不明白为什么不同操作系统的输出不同。
更新 2
...还有这个
Console.WriteLine((d / 100D).ToString("P3", CultureInfo.GetCultureInfo("de-DE")))
在 Win7 上的结果:
1,230%
在 Win 10 和 Windows Server 2012 上我得到了这个结果:
1,230 %
很奇怪,相同的文化,不同的输出...
"P"
格式说明符是 culture-sensitive,根据 Microsoft .NET Standard Numeric Format Strings documentation。
在 Decimal.ToString(string, IFormatProvider)
重载中使用 CultureInfo.InvariantCulture
实现跨系统的一致 culture-agnostic 结果:
Dim d As Decimal = 1.23
Console.WriteLine((d / 100D).ToString("P3", CultureInfo.InvariantCulture))
更新
CultureInfo.InvariantCulture
告诉格式化方法忽略 thread-specific 区域性设置并使用随时间和机器保持一致的特殊通用区域性。
根据特定的文化,不同版本的 Windows:
One comment on different question 表明这是在 Windows 7 和 Windows 8 之间更改的。
不过,我觉得你的问题比较哲学。 Culture-sensitive 随着时间的推移,字符串看起来总是不同的。
一件事是软件部分 - 在 Windows 7 之前,百分比模式甚至不可用,因此您的字符串在 Vista 上可能已经看起来不同了。
另一件事是现实世界及其不断变化的条件。想象一下这种情况:明年您的国家可能会出台新的语法规则,其中将指定要使用的不同格式。 Microsoft 将发布更新,调整默认设置以匹配这些规则。但是,在给定的时间点,有些用户不会安装更新,因此会得到不同的字符串。有些用户可能多年不更新。
您的程序重新实现 culture-dependent 细节是否有意义,或者这应该是操作系统的责任?拥有自己的文化规则将使您的程序看起来很奇怪,因为该计算机上的大多数其他程序将具有与 OS 一致的文化规则(除非它们的作者也决定重新实现文化)。当然,还有一个问题是微软是否应该在 Windows 版本之间的百分比格式中添加 space 。但恐怕那艘船几年前就已经航行了,我们只能忍受它。同样,它会影响 culture-sensitive 字符串,这些字符串无论如何都容易随时间发生变化。
如果你真的必须这样做,我想你最好的选择是为每个线程克隆文化并设置 CultureInfo.NumberFormat.PercentPositivePattern = 1;
我有两个盒子:一个 Win7 和另一个 Win10(还有一个 Windows Server 2012 盒子,它的行为与我的 Win10 盒子相同)。
所有盒子上都安装了 .NET 版本 4.5.2。
当我运行以下代码时:
Dim d As Decimal = 1.23
Console.WriteLine((d / 100D).ToString("P3"))
然后我在 Win7 上得到这个结果:
1,230%
在 Win 10 和 Windows Server 2012 上我得到了这个结果:
1,230 %
注意百分号前的 space。
谁能帮我看看为什么会这样?我仔细检查了.NET版本,它们都是4.5.2,所以这可能与操作系统有关吗?
非常感谢大家。
更新:
使用
Console.WriteLine((d / 100D).ToString("P3", CultureInfo.InvariantCulture))
我在所有机器上都得到了这个结果:
1,230 %
但是当输出
Console.WriteLine(Thread.CurrentThread.CurrentCulture.Name)
在我得到的所有机器上
de-DE
我原以为文化一定会表现出不同的东西,因为会产生不同的结果,但由于一切都是去德的,我仍然不明白为什么不同操作系统的输出不同。
更新 2
...还有这个
Console.WriteLine((d / 100D).ToString("P3", CultureInfo.GetCultureInfo("de-DE")))
在 Win7 上的结果:
1,230%
在 Win 10 和 Windows Server 2012 上我得到了这个结果:
1,230 %
很奇怪,相同的文化,不同的输出...
"P"
格式说明符是 culture-sensitive,根据 Microsoft .NET Standard Numeric Format Strings documentation。
在 Decimal.ToString(string, IFormatProvider)
重载中使用 CultureInfo.InvariantCulture
实现跨系统的一致 culture-agnostic 结果:
Dim d As Decimal = 1.23
Console.WriteLine((d / 100D).ToString("P3", CultureInfo.InvariantCulture))
更新
CultureInfo.InvariantCulture
告诉格式化方法忽略 thread-specific 区域性设置并使用随时间和机器保持一致的特殊通用区域性。
根据特定的文化,不同版本的 Windows:
One comment on different question 表明这是在 Windows 7 和 Windows 8 之间更改的。
不过,我觉得你的问题比较哲学。 Culture-sensitive 随着时间的推移,字符串看起来总是不同的。
一件事是软件部分 - 在 Windows 7 之前,百分比模式甚至不可用,因此您的字符串在 Vista 上可能已经看起来不同了。
另一件事是现实世界及其不断变化的条件。想象一下这种情况:明年您的国家可能会出台新的语法规则,其中将指定要使用的不同格式。 Microsoft 将发布更新,调整默认设置以匹配这些规则。但是,在给定的时间点,有些用户不会安装更新,因此会得到不同的字符串。有些用户可能多年不更新。
您的程序重新实现 culture-dependent 细节是否有意义,或者这应该是操作系统的责任?拥有自己的文化规则将使您的程序看起来很奇怪,因为该计算机上的大多数其他程序将具有与 OS 一致的文化规则(除非它们的作者也决定重新实现文化)。当然,还有一个问题是微软是否应该在 Windows 版本之间的百分比格式中添加 space 。但恐怕那艘船几年前就已经航行了,我们只能忍受它。同样,它会影响 culture-sensitive 字符串,这些字符串无论如何都容易随时间发生变化。
如果你真的必须这样做,我想你最好的选择是为每个线程克隆文化并设置 CultureInfo.NumberFormat.PercentPositivePattern = 1;