C# 为什么.NET是;德奇;区域性编号组分隔符在本地和Azure上不同?

C# 为什么.NET是;德奇;区域性编号组分隔符在本地和Azure上不同?,c#,.net,azure,localization,number-formatting,C#,.net,Azure,Localization,Number Formatting,在本地桌面和Azure中运行时,我看到一个不同的Unicode字符作为“de CH”区域性的数字组分隔符 当以下代码在.NET Core 3.1或.NET Framework 4.7.2的“我的桌面”上运行时,它会输出2019,看起来像撇号,但不同 当在Azure中运行时,例如在.NET Core 3.1(在基于Windows的应用程序服务上)上运行的Azure函数中运行或(稍微修改)时,它会导致0027,一个标准的ASCII撇号 using System; using System.Linq;

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

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

当在Azure中运行时,例如在.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中工作


为什么会有差异?

关于你的问题,我进行了一系列测试

当前调查进度:

问题:区域性信息在WebApp窗口中返回错误的值(0027)

调查进展:

为同一操作系统设置测试环境,确认该值由底层操作系统返回,并确认0027应该是此操作系统下的正确返回值

下图显示了2019和0027所代表的字符,它们都表示撇号

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
    );


您可以参考此文档:

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

CultureInfo和RegionInfo数据表示文化、区域和管理 或用户对文化环境的偏好。申请不应 根据该数据的稳定性做出任何假设。唯一的 例外(这是一条规则,所以当然有例外)是 CultureInfo.InvariantCulture。CultureInfo.InvariantCulture是 应该保持稳定,即使在版本之间

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

  • 最明显的原因是数据中有一个bug,我们不得不进行更改。(信不信由你,我们会犯错误;-))在这种情况下,我们的用户(以及你的用户)需要文化上正确的数据,因此我们必须修复该漏洞,即使它破坏了现有的应用程序
  • 另一个原因是文化偏好可以改变。这种情况有很多种可能发生,但确实发生了:
    • 全球意识、跨文化交流、计算机角色的变化等等都会影响文化偏好
    • 国际条约、贸易等可以改变价值观。欧元的采用将许多国家的货币符号改为€
    • 国家或地区法规也会影响这些价值观
    • 单词的首选拼写可能会随着时间的推移而改变
    • 首选日期格式等可以更改
  • 一个区域性可能存在多个首选项。首选的最佳选择可以随着时间的推移而改变
  • 用户可以覆盖某些值,如日期或时间格式。这些可以在没有用户重写的情况下被请求,但是我们建议应用程序考虑使用用户重写。
  • 用户或管理员可以创建替换区域性,用特定于公司、特定于区域或标准数据的其他变体替换区域性的通用默认值。
    • 某些区域性的首选项可能因设置而异。企业的形式可能比网吧更正式
    • 企业可能需要整个组织的特定日期格式或时间格式
  • 同一自定义区域性的不同版本,或一台计算机上的自定义区域性版本和另一台计算机上的纯windows区域性版本
因此,如果您使用特定的日期/时间格式格式化字符串,然后 稍后尝试对其进行分析,如果版本更改,分析可能会失败,如果 如果框架版本更改(更新的数据),或者 一种风俗文化被改变了。如果需要将数据持久化到 可靠的格式,选择二进制方法,提供自己的格式或 使用不变量文化

即使在不改变数据的情况下,记住使用不变量仍然是一个难题 好主意。如果你有不同的想法。以及类似的语法 1000.29,则如果客户端希望 1.000,29. 我在应用程序中看到过这个问题,这些应用程序没有意识到用户的文化与开发人员的文化是不同的 文化使用不变量或其他技术可以解决这种问题 问题

当然,对于当前用户,不能同时显示“正确”的内容 如果区域性数据发生变化,则实现完美的往返。一般来说 我建议使用不变量文化或其他方法来持久化数据 不可变的格式,并始终使用适当的格式化API 展示。您的应用程序将有自己的要求,所以请考虑 仔细检查

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

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

  • 允许用户明确指定使用的格式
  • 首先从字符串中删除除数字、减号和小数分隔符以外的所有字符,然后再尝试分析此字符串。请注意,您首先需要知道正确的十进制分隔符。没有办法正确地猜测这一点,猜测错误可能会导致重大问题
尽可能避免解析格式为用户友好的数字。只要可能,请尝试以严格定义的(不变的)格式请求数字。

\u0027是撇号,\u2019