当前文化,不变文化,现代文化与装置文化的差异
System.Globalization.CultureInfo
与CurrentCulture
, InvariantCulture
, CurrentUICulture
和InstalledUICulture
什么不同?
我会试着给出比这个更有见地的答案。
CurrentCulture应该用于格式化。 也就是说,数字,货币,百分比,date和时间应该总是与这种文化格式,然后才显示给用户 。 这里有几个例子:
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);
一个重要的事情要注意的是,你永远不应该使用float
也不是double
存储货币相关的信息( decimal
是正确的select)。
CurrentCulture
的另一个常见用例是Locale-awareparsing。 您的应用程序应始终允许用户以区域格式提供input:
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
。 其原因是,我想与其他开发人员进行交stream:这是将显示给最终用户的东西。 这是FxCop忽略这个参数的原因之一。
另一方面, InvariantCulture应该被用于可靠地将上述类别之一转换为文本表示。 所以如果你想通过networking传输DateTime
, float
, double
或者类似的对象,把它存储到数据库或者某种文本文件(包括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
提供的date/时间格式实际上与en-US完全相同。 虽然可靠,但并不完全正确。 真正应该使用的是ISO8601可互换date和时间格式 。 出于某种原因,微软甚至不提供这样的模式(最接近的是可分类模式 – “s”和通用模式 – “u”,它们只与ISO8601格式相似),您需要创build自己的像这样:
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
原因非常简单:在法语操作系统上使用float格式(使用法语区域格式)被格式化为类似于10,5的types,并且Version
类需要Culture-invariantinput。
CurrentUICulture负责为您的应用程序加载适当的可翻译资源。 也就是说,它应该用于显示正确的文本信息,颜色和图像。
在Asp.Net应用程序中,如果你想出于某种原因实现CSS本地化机制(能够覆盖每种语言的CSS定义), CurrentUICulture
是一个很好的方法(假设你实际上从web浏览器读取这个属性)。
同样,如果你想实现语言切换机制, CurrentUICulture
是应该被覆盖的。
InstalledUICulture连接到默认OS UI区域设置。 正如MSDN所说:
该属性相当于Windows API中的GetSystemDefaultUILanguage。
要真正理解这个属性是什么,我们需要深入一些理论。 有不同的Windows产品线:
- 单一语言(即英文,法文,德文,日文等)
- MUI(即多语言用户界面 – 英文基本操作系统和语言包)
对于单一语言产品系列,InstalledUICulture将始终返回操作系统语言,而对于MUI,它应始终返回英语(美国)(又名en-US)。 它有用吗? 我不知道,我从来不需要这样的信息。 而且我个人还没有看到利用这个属性的程序。
从这个答案采取:
CurrentCulture是系统的默认用户区域设置的.NET表示forms。 这控制了默认的数字和date格式等。
CurrentUICulture指的是默认的用户界面语言,这是Windows 2000中引入的一种设置。这主要是关于应用程序的UI本地化/翻译部分。
无论系统configuration的区域选项是什么,都将是.NET应用程序中的“当前”值。
通常他们都是一样的。 但是在我的系统中,他们会有所不同:我更喜欢德文格式的数字和date,所以CurrentCulture会是德语,但我也更喜欢我的所有英文应用程序,所以CurrentUICulture会是英文。