What we should know about CurrentCulture and CurrentUICulture?

From the first version .NET Framework has rich set of functions that allow you to make your Application to be World ready. And the most interesting place to start is System.Globalization namespace which contains CultureInfo class. But if you have explored this class already, you probably found that it has two very similar properties both return values of CultureInfo type: CurrentCulture and CurrentUICulture. So what is the difference between them?

The short answer is MUI (Multilingual User Interface): If on your or your customer's PC is installed a single language of Windows OS, these properties contains equal data, no matter what language is it. But some editions of Windows (Windows Vista Ultimate, for example) allow installing any number of additional languages (and whole bunch of locale settings like date and number formats) and switching between them.

Let's look closer what if an additional UI language support is installed and activated. I bolded the last word because if a MUI pack has been just installed but not switch to, both properties still keep the same data even if user has customized his locale settings. I ran the code below on Windows Vista en-US version with has customized date and time parameters as "dd/MM/yy HH:mm:ss" instead of traditional US formats:

 // CurrentCulture demo:
 System.Globalization.CultureInfo currentCulture = System.Globalization.CultureInfo.CurrentCulture;
 MessageBox.Show(
    String.Format("currentCulture.DateTimeFormat.FullDateTimePattern: {0}\r\ncurrentCulture.NumberFormat.CurrencySymbol: {1}\r\nDateTime.Now.ToString(currentCulture): {2}", 
        currentCulture.DateTimeFormat.FullDateTimePattern,
        currentCulture.NumberFormat.CurrencySymbol,
        DateTime.Now.ToString(currentCulture)), 
    currentCulture.EnglishName);
 
 // CurrentUICulture demo:
 System.Globalization.CultureInfo currentUICulture = System.Globalization.CultureInfo.CurrentUICulture;
 MessageBox.Show(
    String.Format("currentUICulture.DateTimeFormat.FullDateTimePattern: {0}\r\ncurrentUICulture.NumberFormat.CurrencySymbol: {1}\r\nDateTime.Now.ToString(currentUICulture)): {2}",
        currentUICulture.DateTimeFormat.FullDateTimePattern,
        currentUICulture.NumberFormat.CurrencySymbol,
        DateTime.Now.ToString(currentUICulture)),
    currentUICulture.EnglishName);
 

and here are results I got:

CurrentCulture on non-MUI PC

CurrentUICulture on non-MUI PC

As you can see, both CurrentCulture and CurrentUICulture return exactly the same locale name (at the title bar) and date/time formats.

Now I'm going to activate preinstalled Russian MUI and re-run the test.

Lang settings - choose a display language

And here are new results:

CurrentCulture on MUI PC

CurrentUICulture on MUI PC

CurrentCulture in second test wasn't changed although CurrentUICulture was: the UI culture contains default formats for Russian language and even my customization has no any affect.

Why it is so important?

If your App just output some data (let say from a database) then using wrong Culture info settings could confuse your users (say "1/3/08 – is it January or March?) but no runtime exception will happen.

But if you expect some user input when you should take a string, parse it into correct format and store or operate with it, wrong locale settings could break your App if format exceptions won't be correctly handled.

Fortunately every culture-critical function in .NET Framework like ToString() or Parse() has several overloads where default (without any parameters) function takes CurrentCulture as a locale information. If I run the code below on my MUI system, the first line will be able to parse my input string successfully:

 string inputDate = "15/11/2008 12:00";
 DateTime parseDateCurrentCulture = DateTime.Parse(inputDate);
 

but this one:

 DateTime parseDateUICulture = DateTime.Parse(inputDate,
    System.Globalization.CultureInfo.CurrentUICulture);
 

fails with FormatException.

So based on these experiments, it's more safe and preferred to use CurrentCulture and try..catch blocks to handle possible exceptions especially when you expect some locale-critical user input:

 try
 {
    DateTime parseDateCurrentCulture = DateTime.Parse(inputDate);
 }
 catch (FormatException)
 {
    MessageBox.Show("Wrong input format!");
 }
 

Technorati Tags: localization