为什么 .NET "de-CH"区域性编号组分隔符在本地和 Azure 上不同?



在本地桌面和 Azure 中运行时,我看到一个不同的 Unicode 字符作为"de-CH"区域性的数字组分隔符。

当以下代码在 .NET Core 3.1 或 .NET Framework 4.7.2 的桌面上运行时,它会输出2019看起来像撇号但并不相同。

当在Azure中运行时,例如在 https://try.dot.net 中或在.NET Core 3.1(在基于Windows的应用程序服务上)上运行的Azure函数中(略有修改),它会产生0027,一个标准的ASCII撇号。

using System;
using System.Linq;
using System.Globalization;
Console.WriteLine(((int)(CultureInfo
.GetCultureInfo("de-CH")
.NumberFormat
.NumberGroupSeparator
.Single())) // Just getting the single character as an int
.ToString("X4") // unicode value of that character
);

这样做的结果是,尝试使用"de-CH"区域性在本地桌面上分析字符串4'200.000(其中撇号是 Unicode0027)失败,但它在 Azure 中有效。

为什么会有差异?

这篇由 Shawn Steele 撰写的Microsoft博客解释了为什么您不应该依赖稳定的特定区域性设置(完全引用,因为它在 MSDN 上不再在线):

https://web.archive.org/web/20190110065542/https://blogs.msdn.microsoft.com/shawnste/2005/04/05/culture-数据-不应该被考虑-稳定-除了-不变/

CultureInfo 和 RegionInfo 数据表示文化、区域、管理员 或用户对文化设置的偏好。 应用程序不应 做出任何依赖于此数据稳定的假设。 唯一的 例外(这是一个规则,所以当然有一个例外)是针对 文化信息.不变文化. 文化信息.不变文化是 应该保持稳定,即使在版本之间也是如此。

文化数据发生变化的原因有很多。 与惠德比 和自定义区域性,列表会变得更长一些。

  • 最明显的原因是数据中存在错误,我们必须进行更改。 (信不信由你,我们会犯错误;-)) 在这种情况下,我们的用户(以及您的用户)想要文化上正确的数据,因此即使它破坏了现有应用程序,我们也必须修复该错误。
  • 另一个原因是文化偏好可以改变。 有很多方法可以发生这种情况,但它确实会发生:
    • 全球意识、跨文化交流、计算机角色的变化等等都会影响一种文化偏好。
    • 国际条约、贸易等可以改变价值观。 欧元的采用将许多国家的货币符号更改为欧元。
    • 国家或地区法规也会影响这些值。
    • 单词的首选拼写可能会随着时间的推移而改变。
    • 首选日期格式等可能会更改。
  • 一种文化可能存在多种偏好。 然后,首选的最佳选择可能会随着时间的推移而改变。
  • 用户可能已覆盖某些值,例如日期或时间格式。 可以在没有用户覆盖的情况下请求这些内容,但我们建议应用程序考虑使用用户替代。
  • 用户或管理员可能已创建替换区域性,将区域性的常见默认值替换为公司特定、区域特定或标准数据的其他变体。
    • 某些区域性可能具有因设置而异的偏好。 企业可能比网吧有更正式的形式。
    • 企业可能需要整个组织的特定日期格式或时间格式。
  • 同一自定义区域性的不同版本,或者在一台计算机上自定义的区域性版本,而在另一台计算机上仅 Windows 区域性

因此,如果您使用特定的日期/时间格式格式化字符串,然后 尝试稍后解析它,如果版本更改,解析可能会失败,如果 计算机已更改,如果框架版本已更改(较新的数据),或者如果 自定义区域性已更改。 如果需要将数据保存在 可靠的格式,选择二进制方法,提供您自己的格式或 使用固定文化。

即使不更改数据,记住使用不变仍然是一个 好主意。 如果你有不同的.和 ,类似内容的语法 1,000.29,然后如果客户端期望 1.000,29. 我在应用程序中看到了这个问题,这些应用程序没有意识到用户的文化与开发人员的文化不同 文化。 使用不变量或其他技术可以解决这种 问题。

当然,您不能同时为当前用户同时显示"正确"的 如果培养数据发生变化,则完美的往返。 所以一般 我建议使用InvariantCulture或其他方法持久化数据 不可变格式,并始终使用适当的格式设置 显示。 您的应用程序将有自己的要求,因此请考虑 他们小心翼翼。

请注意,对于排序规则(排序顺序/比较),甚至不变 行为可以改变。 您需要使用排序版本控制来获取 如果您需要始终稳定的排序顺序,则可以围绕这一点。

如果需要自动分析格式化为用户友好的数据,有两种方法:

  • 允许用户显式指定使用的格式。
  • 首先从字符串中删除除数字、减号和小数点分隔符之外的所有字符,然后再尝试解析它。请注意,您首先需要知道正确的小数分隔符。没有办法猜错这一点,猜错可能会导致重大问题。

尽可能避免解析格式化为用户友好的数字。相反,只要有可能,请尝试以严格定义(不变)格式请求数字。

最新更新