Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

.net - Difference between CurrentCulture, InvariantCulture, CurrentUICulture and InstalledUICulture

What is the difference between CurrentCulture, InvariantCulture, CurrentUICulture and InstalledUICulture from System.Globalization.CultureInfo?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would try to give a bit more insightful answer than this one.

CurrentCulture should be used for formatting. That is, Numbers, Currencies, Percentages, Dates and Times should always be formatted with this culture before displaying them to user. Few examples here:

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

One important thing to note is that you should never use float nor double for storing currency related info in the first place (decimal is the right choice).
The other common use case for CurrentCulture is Locale-aware parsing. Your application should always allow users to provide input in their regional format:

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

Please note that I always provide IFormatProvider parameter, although it is implied and assumed to be CultureInfo.CurrentCulture. The reason for it is, I want to communicate with fellow developers: this is something that will be displayed to end users. This is one of the reasons why FxCop treats omitting this parameter as error.


InvariantCulture on the other hand should be used to convert reliably one of the classes mentioned above to its textual representation. So if you want to for example transmit DateTime, float, double or similar object via network, store it to database or some kind of text file (including XML), you should always use 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);

A thing to note here is that date/time format offered by InvariantCulture is actually exactly the same as en-US. Although it is reliable, it is not exactly correct. What really should be used is ISO8601 Interchangeable Date & Time Format. For some reason Microsoft does not even provide such pattern (the closest ones are Sortable pattern - "s" and Universal pattern - "u" which only resembles ISO8601 format), you would need to create your own like this:

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

Quite important side note: IFormatProvider is actually required here as omitting this parameter may result in serious errors. I once had to fix a defect on French OS. The code was like this:

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

The reason was very simple: float formatted on French OS (with French regional formatting) was formatted to something like 10,5 and Version class requires Culture-invariant input.


CurrentUICulture is responsible for loading appropriate translatable resources for your application. That is, it should be use for displaying correct text messages, colors and images.
In Asp.Net application if you want to for some reason implement CSS Localization Mechanism (ability to override CSS definitions per language), CurrentUICulture is good way to go (provided that you actually read this property from web browser).
Likewise if you want to implement language switching mechanism, CurrentUICulture is the one that should be overridden.


InstalledUICulture is wired to Default OS UI Locale. As MSDN says:

This property is the equivalent of GetSystemDefaultUILanguage in the Windows API.

To actually understand what this property is, we need to dig into some theory. There are different Windows product lines:

  • single language (i.e. English, French, German, Japanese, etc.)
  • MUI (that is Multilingual User Interface - English base OS and Language Packs)

For single language product lines, InstalledUICulture will always return Operating System language, whereas for MUI it should always return English (United States) aka en-US. Is it useful? I don't know, I never needed such an information. And personally I haven't seen program that took advantage of this property.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...