首页 > 解决方案 > 为什么 .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(其中撇号为 Unicode 0027)失败,但它在 Azure 中有效。

为什么有区别?

标签: c#.netazurelocalizationnumber-formatting

解决方案


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

https://web.archive.org/web/20190110065542/https://blogs.msdn.microsoft.com/shawnste/2005/04/05/culture-data-shouldnt-be-considered-stable-except-for-不变/

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

文化数据可以改变的原因有很多。使用 Whidbey 和 Custom Cultures,列表会变得更长一些。

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

因此,如果您使用特定日期/时间格式格式化字符串,然后尝试稍后解析它,如果版本更改、机器更改、框架版本更改(更新的数据)或自定义文化,解析可能会失败被改变了。如果您需要以可靠的格式保存数据,请选择二进制方法,提供您自己的格式或使用 InvariantCulture。

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

当然,如果文化数据发生变化,您不能同时为当前用户提供“正确”显示和完美的往返。因此,通常我建议使用 InvariantCulture 或其他不可变格式保存数据,并始终使用适当的格式化 API 进行显示。您的应用程序将有自己的要求,因此请仔细考虑。

请注意,对于排序规则(排序顺序/比较),即使是不变的行为也可以改变。如果您需要始终如一的稳定排序顺序,则需要使用 Sort Versioning 来解决这个问题。

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

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

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


推荐阅读