Creating/Extending a Culture

I previously wrote this article in my blog, Think Big!.

Introduction

Haven't you ever used a culture and want to extend it by changing e.g. the currency symbol?

Haven't you ever wanted to create a custom culture for formatting purposes?

Answers will vary depend on the developer and the people he target for his application.

Overtime, more and more languages are supported with the .NET Framework. However, not all languages of the world are available with .NET.You can create a custom culture. Some examples of when creating custom cultures can be useful are to support a minority within a region or to create subcultures for different dialects.

Custom cultures and regions can be created with the class CultureAndRegionInfoBuilder in the namespace System.Globalization. This class is resides in the assembly sysglobl.dll -you need to reference it of course.-

Now, we are going to create a custom culture that extends the U.S. English culture. This culture is for New York. We'll step further and change some of the characteristics of the base culture (en-US) to accommodate our needs for a good example.

Implementation

We'll start by referencing the assembly sysglobl.dll and add a using statement for the namespace System.Globalization.

sysglobl.dll is very tiny assembly. It contains only one class CultureAndRegionInfoBuilder and one enumeration only CultureAndRegionModifiers -we'll see that soon.-

Then, We instantiate a new instance of CultureAndRegionInfo class. That class is the key class for creating/extending a culture. It contains besides it's instance members, a static method for unregistering your baby -after registering it of course.-
 

CultureAndRegionInfoBuilder builder = new CultureAndRegionInfoBuilder("en-US-NY", CultureAndRegionModifiers.None);

The constructor of CultureAndRegionInfoBuilder class requires two parameters. The first is the name of the new culture. The second can one of the three values defined by the CultureAndRegionModifiers enumeration. And that parameter is used to identify the new culture.

The values of CultureAndRegionModifiers are

  • None
    For new cultures and the cultures that extends existing ones.
  • Neutral
    For new cultures. such as English, French, etc.
  • Replacement
    For the cultures that you intend to be a replacement of existing culture in .NET Framework or even Windows.

In cultures world, There's a unique name for every culture. And that name follows a naming convention that xx-XX. The first lowercase xx is for language like en, fr, es, and so on. The second uppercase XX is for the country/region like US, FR, and ES. So an example like de-DE is for German in Germany.

There's exceptions to these rules. First, There's languages like Dhivehi and Konkani that's abbreviated to three letters like div and kok. Also, there're two neutral cultures zh-CHS and zh-CHT for Simplified and Traditional Chinese. In addition, There're cultures that have the suffix -Cyrl and -Latn for defining the script Cyrillic or Latin.
See RFC 1766 Standards.

After instantiating a new object of type CultureAndRegionInfoBuilder you need to initialize its properties with a valid values. For the example we have we load the values from the parent culture en-US because we intend to extend it. Actually, There's no rules to admit in loading the values for the new culture. You can load it from existing culture or you can do it the hard way and take it all. Also, We set the Parent property to the parent culture that we wish to extend.

CultureInfo parent = new CultureInfo("en-US");

builder.LoadDataFromCultureInfo(parent);

builder.LoadDataFromRegionInfo(new RegionInfo("US"));

builder.Parent = parent;

You might review the properties of both CultureInfo and RegionInfo and compare it to the properties of CultureAndRegionInfoBuilder to know exactly why we are loading both objects.

Now comes the hardest part, changing the properties to accommodate our needs. Also, setting the name of the new culture.

In the last few lines we changed the region English and native name also the culture English and native name.

In addition, We changed the currency symbol from the dollar sign $ to an asterisk *.
 

builder.RegionEnglishName = "New York";

builder.RegionNativeName = "New York";

builder.CultureEnglishName = "New York (United States)";

builder.CultureNativeName = "New York (United States)";builder.NumberFormat.CurrencySymbol = "*";

Notice the difference between English name and native name. For non-English cultures you might change the native name. A good example is French for France, English name is "French" and native name is "français".

Here comes the hottest part, registering your new culture:

builder.Register();

You might get an exception of type InvalidOperationException if you tried to re-register it, or even if you chose a name that's existed and you are not creating a replacement culture.

Testing

Now, Test your new culture:
 

CultureInfo newYork = new CultureInfo("en-US-NY");

double money = 100.99;

Console.WriteLine("I have {0}", money.ToString("C", newYork));// "C" means currency formatting


Congratulations! You have finished the example.

There's also things that you might take into account:

  1. You can unregister your created culture by using the static method Unregister of the type CultureAndRegionInfoBuilder.
     
    CultureAndRegionInfoBuilder.Unregister("en-US-NY");

  2. After creating the desired culture and you desired not to register it immediately you can save it as XML and load it later.
     

    // Saving the culture

    builder.Save("D:\\New York Culture.xml");

    // Loading the saved cultureCultureAndRegionInfoBuilder.CreateFromLdml("D:\\New York Culture.xml");


  3. Windows saves the custom cultures you create in the folder %windir%Globalization.
  4. You are not ended using the custom culture in your .NET code only. You can go to Regional and Language Settings in Control Panel and change the culture to your created one and that affects the entire system.

References

Links are subject to change if you found a bad link in our site please report it to us as soon as possible.

Code Sample

Code sample is attached with the article.


Similar Articles