【问题标题】:Difference between CurrentCulture, InvariantCulture, CurrentUICulture and InstalledUICultureCurrentCulture、InvariantCulture、CurrentUICulture 和 InstalledUICulture 之间的区别
【发布时间】:2011-06-30 22:24:42
【问题描述】:

CurrentCultureInvariantCultureCurrentUICultureInstalledUICultureSystem.Globalization.CultureInfo 有什么区别?

【问题讨论】:

标签: .net internationalization globalization


【解决方案1】:

取自this answer

CurrentCulture 是默认用户区域设置的 .NET 表示形式 系统的。这控制默认的数字和日期格式和 之类的。

CurrentUICulture 是指默认的用户界面语言,一种 Windows 2000 中引入的设置。这主要是关于 UI 您应用的本地化/翻译部分。

系统配置的任何区域选项都将是 .NET 应用程序中的“当前”值。

通常它们都是相同的。但在我的系统上,它们会是 不同:我更喜欢德语格式的数字和日期,所以 CurrentCulture 将是德国人,但我也更喜欢我的所有应用程序 英文,所以 CurrentUICulture 将是英文。

【讨论】:

    【解决方案2】:

    我会尝试给出比this one更有洞察力的答案。

    CurrentCulture 应该用于格式化。也就是说,数字、货币、百分比、日期和时间应该始终按照这种文化进行格式化,然后将它们显示给用户。这里的几个例子:

    const string CURRENCY_FORMAT = "c";
    const string PERCENTAGE_FORMAT = "p";
    
    DateTime now = DateTime.UtcNow; // all dates should be kept in UTC internally
    // convert time to local and format appropriately for end user
    dateLabel.Text = now.ToLocalTime().ToString(CultureInfo.CurrentCulture);
    
    float someFloat = 12.3456f;
    // yields 12,3456 for pl-PL Culture
    floatLabel.Text = someFloat.ToString(CultureInfo.CurrentCulture);
    // yields 12,35 zł for pl-PL Culture - rounding takes place!
    currencyLabel.Text = someFloat.ToString(CURRENCY_FORMAT, CultureInfo.CurrentCulture);
    // yields 1234,56% for pl-PL Culture - 1.0f is 100%
    percentageLabel.Text = someFloat.ToString(PERCENTAGE_FORMAT, CultureInfo.CurrentCulture);
    

    需要注意的重要一点是,您首先不应该使用floatdouble 来存储与货币相关的信息(decimal 是正确的选择)。
    CurrentCulture 的另一个常见用例是区域感知解析。您的应用程序应始终允许用户以其区域格式提供输入:

    float parsedFloat;
    if (float.TryParse(inputBox.Text, NumberStyles.Float, CultureInfo.CurrentCulture, out parsedFloat))
    {
        MessageBox.Show(parsedFloat.ToString(CultureInfo.CurrentCulture), "Success at last!");
    }
    

    请注意,我总是提供IFormatProvider 参数,尽管它是隐含的并假定为CultureInfo.CurrentCulture。原因是,我想和其他开发者交流:这是要展示给最终用户的东西。这也是 FxCop 将省略此参数视为错误的原因之一。


    另一方面,

    InvariantCulture 应该用于可靠地将上述类之一转换为其文本表示。因此,如果您想通过网络传输 DateTimefloatdouble 或类似对象,将其存储到数据库或某种文本文件(包括 XML)中,您应该始终使用InvariantCulture:

    float someFloat = 1234.56f;
    // yields 1234.56
    string internalFloat = someFloat.ToString(CultureInfo.InvariantCulture);
    DateTime now = DateTime.UtcNow;
    // yields something like 04/16/2011 19:02:46
    string internalDateAndTime = now.ToString(CultureInfo.InvariantCulture);
    

    这里需要注意的是InvariantCulture 提供的日期/时间格式实际上与en-US 完全相同。尽管它是可靠的,但它并不完全正确。真正应该使用的是ISO8601 Interchangeable Date & Time Format。出于某种原因,Microsoft 甚至不提供这样的模式(最接近的是可排序模式 - “s”和通用模式 - “u”,它只类似于 ISO8601 格式),您需要像这样创建自己的:

    const string iso8601Pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    string iso8601Formatted = now.ToString(iso8601Pattern);
    

    非常重要的附注:IFormatProvider 在此处实际上是必需,因为省略此参数可能会导致严重错误。我曾经不得不修复法语操作系统的一个缺陷。代码是这样的:

    float dbVersion = // some kind of logic that took float from database
    string versionString = dbVersion.ToString(); // culture-aware formatting used
    Version ver = new Version(versionString); // exception thrown here
    

    原因很简单:在法语操作系统上格式化的浮点数(使用法语区域格式)被格式化为 10,5 之类的东西,而Version 类需要文化不变的输入。


    CurrentUICulture 负责为您的应用程序加载适当的可翻译资源。也就是说,它应该用于显示正确的文本消息、颜色和图像。
    在 Asp.Net 应用程序中,如果您出于某种原因想要实现 CSS 本地化机制(能够覆盖每种语言的 CSS 定义),CurrentUICulture 是不错的选择(前提是您实际上是从 Web 浏览器读取此属性)。
    同样,如果你想实现语言切换机制,CurrentUICulture 是应该被覆盖的。


    InstalledUICulture 已连接到默认 OS UI 区域设置。正如MSDN 所说:

    此属性相当于 Windows API 中的 GetSystemDefaultUILanguage。

    要真正理解这个属性是什么,我们需要深入研究一些理论。有不同的 Windows 产品线:

    • 单一语言(即英语、法语、德语、日语等)
    • MUI(即多语言用户界面 - 英语基础操作系统和语言包)

    对于单一语言产品线,InstalledUICulture 将始终返回操作系统语言,而对于 MUI,它应始终返回英语(美国),即 en-US。有用吗?我不知道,我从来不需要这样的信息。而且我个人还没有看到利用这个属性的程序。

    【讨论】:

    • 您不需要使用上述 ISO8601 模式字符串(不再?)。这也应该有效:myDate.ToString("o")oO 格式字符串会将日期/时间转换为 ISO 8601 格式。
    猜你喜欢
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多