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

Comments

  • Anonymous
    November 09, 2008
    PingBack from http://www.tmao.info/what-we-should-know-about-currentculture-and-currentuiculture/

  • Anonymous
    November 09, 2008
    The current version of DateTime (since 2.0 I think) also has a TryParse method, which saves you the overhead of stack unwinding (it's an edge case, but I'd argue you are using exceptions to implement functionality in the last code snippet). -- Henkk

  • Anonymous
    November 09, 2008
    Correct. But you should provide a default date within TryParse() at least. It is safe to use it in case if you have a date that you can default to.

  • Anonymous
    January 15, 2015
    A bit late for this comment, but... Try changing your "date, time or number format" in the control panel. Choose e.g. "Norway". You will see that CurrentCulture reflects this setting. CurrentUICulture, as you point out, reflects the OS language. Thus: Use CurrentCulture to format date and numbers. NOT CurrentUICulture (which ONLY controls what translation you should show the user by default, though it is polite to ask first). In my case: I am a Norwegian living in Sweden. I have used the original English version of operating systems since the eighties, but I have always chosen Norwegian keyboard layout and Norwegian regional settings (that control date and number format). Many installers and apps manage to get this completely wrong, assuming e.g. that keyboard layout says anything about the preferred UI language. It does not. -- Rune