

Working with Culture & Regions:

Application Culture & UICulture

As we discussed in the previous article, dealing with culture is very important, especially when working with dates and numbers. For that reason, your application will always have an instance of the CultureInfo class defined as its "CurrentCulture" - a fallback instance for all the situations where you don't specifically state which culture should be used e.g. for outputting a number. Unless you change this property, which exists on the CultureInfo class, it will be the same as the culture used by your operating system. Here's a simple way to check it:

Console.WriteLine("Current culture: " + CultureInfo.CurrentCulture.Name);

In this article, we will use the CultureInfo class all the time, so don't forget to include it with the using statement, as shown in the top of the example.

The example will output the culture used by your application, e.g. "en-US" for a computer running with the English language in the United States. If you live in Germany and your computer uses the German language, the result will instead be "de-DE". In other words, the two first letters specify the language, while the last two letters specify the country or region.

However, it might very well be that you want more control of which culture is used by your application. For instance, if your application uses the English language all over the place, does it make sense to output numbers in a German or Swedish format just because the computer of your user specifies it? Perhaps it does, but if not, you can very easily specify a new default/fallback culture, using the CurrentCulture property again:

CultureInfo.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine("Current culture: " + CultureInfo.CurrentCulture.Name);

float largeNumber = 12345.67f;
Console.WriteLine("Number format (Current culture): " + largeNumber.ToString());

Console.WriteLine("Number format (German): " + largeNumber.ToString(germanCulture));

We basically go in and overrule the CurrentCulture property by setting it to an en-US culture. Then we output it, along with a large, floating point number. You will see that the result is a number formatted the way it is in English. In the last couple of lines, we illustrate how you can, of course, overrule the fallback culture by passing another CultureInfo instance to the ToString() method - in this case the number will be outputted in a German format as well. The resulting output of this example should look something like this:

Current culture: en-US
Number format (Current culture): 12345.67
Number format (German): 12345,67

CurrentCulture vs. CurrentUICulture

You may notice that the CultureInfo also has a property called CurrentUICulture. This property is only relevant if you're using resource files for localizing a user interface - in that case, your application will know which versions of the resource files should be loaded, based on the CurrentUICulture property. For all other purposes, including the formatting of numbers, dates and so on, you should use the CurrentCulture property.

CurrentCulture and Threads

We have not really talked about threads yet, but they are basically a concept which will allow your application to work on several things at the same time. When a .NET application is started, a single thread is created and only this thread will be used unless you specifically create a new one, using one of the many multi-threading strategies of the framework. I mention it here because it's also very relevant when it comes to the fallback culture of your application. In fact, CultureInfo.CurrentCulture is basically a shortcut to the Thread.CurrentThread.CurrentCulture property, which means that whenever you define the CurrentCulture, it's only valid for the current thread.

Before .NET framework version 4.5, you would have to manually specify the culture of each new thread you created. However, in .NET 4.5, the CultureInfo.DefaultThreadCurrentCulture property was introduced. When you set it, each new thread created will use this culture as well, and it's just as easy to use as the CurrentCulture property:

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE");

But what about the existing thread? Well actually, if you have not already defined another culture for the CurrentCulture property, setting the DefaultThreadCurrentCulture property will also be applied to the CurrentCulture property. In other words, it makes sense to use the DefaultThreadCurrentCulture instead of CurrentCulture if you plan on using multiple threads in your application - it will take care of all scenarios.


By using the CultureInfo.CurrentCulture and/or the CultureInfo.DefaultThreadCurrentCulture properties, you can define a fallback culture for your application - it will always be used whenever a number or a date is being outputted, unless you specifically overrule this in each situation.
