What is the difference between CurrentCulture
, InvariantCulture
, CurrentUICulture
and InstalledUICulture
from System.Globalization.CultureInfo
?
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:
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.