Understanding locale & culture "display" names


Between Microsoft.Net’s CultureInfo and the Window’s NLS GetLocaleInfoEx() APIs locales/cultures have several names intended for human display.  Note that these names are intended for human use, for machine readable names the “en-US” type name should be used.


Basically we have 3 localizations of 3 types of names.  We have the “language” name, the “region” name, and the “display” name.  Each name can be available in one of 3 forms: the “english” name, the “native” name, and the “localized” name.  Note that the localized name isn’t always available, in which case one of the other forms is used.


Here’s a list of the potential names you’d see (assuming your User Interface language is set to French and the French resources are available)

























 


Display Name


Language Name


Region Name


English Name


German (Switzerland)


German


Switzerland


Native Name


Deutsch (Schweiz)


Deutsch


Schweiz


Localized Name (if UI language is French)


Allemand (Suisse)


Allemand


Suisse


To get those values, these are the APIs you’d use.  Top is the GetLocaleInfoEx() LCTYPE, bottom is the .Net class and property: 

























 


Display Name


Language Name


Region Name


English Name


n/a in NLS


CultureInfo.EnglishName


LOCALE_SENGLANGUAGE


CultureInfo.Parent.EnglishName


LOCALE_SENGCOUNTRY


RegionInfo.EnglishName


Native Name


n/a in NLS


CultureInfo.NativeName


LOCALE_SNATIVELANGNAME CultureInfo.Parent.NativeName


LOCALE_SNATIVECTRYNAME


RegionInfo.NativeName


Localized Name


LOCALE_SLANGUAGE


CultureInfo.DisplayName


LOCALE_SLANGDISPLAYNAME


CultureInfo.Parent.DisplayName


LOCALE_SCOUNTRY RegionInfo.DisplayName


Notice that .Net doesn’t directly have the concept of a Language Name, but generally the Neutral culture that is the parent of a specific culture is named after the language (since it is region neutral), so we can use that.


 


Also in Windows the DisplayName (LOCALE_SLANGUAGE) is intended for display, so English and Native versions are not normally available.  The one exception is that for a custom locale the resources will not be available, so in that case the system will use the native name provided by the custom locale, or the english name if the UI language is English.


 


Sample C# code retrieving these names in .Net follows: 

using System;
using System.Globalization;
using System.IO;

public class Sample
{
    public static void Main()
    {
        StreamWriter writer = new StreamWriter(“out.txt”);


        foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
        {
            writer.WriteLine(“{0} ({1})”, culture.DisplayName, culture.Name);
            writer.WriteLine(“Name: {0}”, culture.Name);
            writer.WriteLine(“Native Name: {0}”, culture.NativeName);
            writer.WriteLine(“English Name: {0}”, culture.EnglishName);
            writer.WriteLine(“Display Name: {0}”, culture.DisplayName);


            if ((culture.CultureTypes & CultureTypes.SpecificCultures) != 0)
            {
                writer.WriteLine(“Parent Name: {0}”, culture.Parent.Name);
                writer.WriteLine(“Parent Native Name: {0}”, culture.Parent.NativeName);
                writer.WriteLine(“Parent English Name: {0}”, culture.Parent.EnglishName);
                writer.WriteLine(“Parent Display Name: {0}”, culture.Parent.DisplayName);
            }
            else
            {
                writer.WriteLine(“Neutral Culture”);
            }


            try
            {
                RegionInfo region = new RegionInfo(culture.Name);
                writer.WriteLine(“Region Name: {0}”, region.Name);
                writer.WriteLine(“Region Native Name: {0}”, region.NativeName);
                writer.WriteLine(“Region English Name: {0}”, region.EnglishName);
                writer.WriteLine(“Region Display Name: {0}”, region.DisplayName);
            }
            catch
            {
                // For geopolitical reasons we cannot create regions from some neutral culture names
                writer.WriteLine(“Unable to create region for {0}”, culture.Name);
            }


            writer.WriteLine();
        }


        writer.Flush();
    }
}