Cook Computing

CurrentCulture and CurrentUICulture

February 4, 2009 Written by Charles Cook

While writing the post yesterday on Expression<TDelegate> another post from Brad Abrams in his Framework Design Guidelines series — Overriding Object.ToString() — triggered my curiosity, this time about the difference between CurrentCulture and CurrentUICulture:

DO string formatting based on the current thread culture when returning culture-dependent information.

To be more explicit, use the CultureInfo instance returned by a thread´┐Żs CurrentCulture property to format any numeric or date, and the one returned by CurrentUICulture to look up any resource. People are often confused between the two properties.

The difference seems to be that CurrentCulture is concerned with internationalization, determining how things such as numbers, currencies, dates, and time are formatted, whereas CurrentUICulture is concerned with localization, determining which language related resources are used to display text in dialogs, menus, etc.

The default value of CultureInfo.CurrentCulture is determined by the regional options for the current user. This is configured using the Regional Options tab in the Regional and Language Options Control Panel applet. On my machine with XP installed I have about 160 different regions to choose from, from Afrikaans to Zulu. The default value of CurrentCulture corresponds to Win32 GetUserDefaultLCID.

The default value of CultureInfo.CurrentUICulture is determined by the the configured UI language for the current user on an MUI version of Windows and the installed language for a localized version of Windows. The default corresponds to Win32 GetUserDefaultUILanguage. On a MUI version of Windows it is configured using the Languages tab of the Regional and Language Options applet.

There is also CultureInfo.InstalledUICulture. This is determined by the UI language for the installed version of Windows. It corresponds to Win32 GetSystemDefaultUILanguage.

CurrentCulture and CurrentUICulture can be set using the corresponding instance properties of the Thread class:


Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");

Note that there is no way of configuring the properties globally for an application. To use non-default values the properties must be explicitly set on every relevant thread.

So, assuming we have the appropriate resources attached to our assembly, we can specify the way numbers, currencies, dates, etc, are displayed independently of which language is used for our UI:


var resMan = new ResourceManager("TestCulture.TestCulture", 
  System.Reflection.Assembly.GetExecutingAssembly());
DateTime dateTime = new DateTime(2008, 12, 25);

Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
string hello = resMan.GetString("Hello");
Console.WriteLine("{0}, {1:d}", hello, dateTime);
// displays "Bonjour, 25/12/2008"

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine("{0}, {1:d}", hello, dateTime);
// displays "Bonjour, 12/25/2008"

Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
hello = resMan.GetString("Hello");
Console.WriteLine("{0}, {1:d}", hello, dateTime);
// displays "Hi, 12/25/2008"