See Also: CultureInfo Members
The System.Globalization.CultureInfo class provides culture-specific information, such as the language, sublanguage, country/region, calendar, and conventions associated with a particular culture. This class also provides access to culture-specific instances of the System.Globalization.DateTimeFormatInfo, System.Globalization.NumberFormatInfo, System.Globalization.CompareInfo, and System.Globalization.TextInfo objects. These objects contain the information required for culture-specific operations, such as casing, formatting dates and numbers, and comparing strings. The System.Globalization.CultureInfo class is used either directly or indirectly by classes that format, parse, or manipulate culture-specific data, such as string, DateTime, DateTimeOffset, and the numeric types.
The System.Globalization.CultureInfo class specifies a unique name for each culture, based on RFC 4646. The name is a combination of an ISO 639 two-letter lowercase culture code associated with a language and an ISO 3166 two-letter uppercase subculture code associated with a country or region.
The format for the culture name is languagecode2>-country/regioncode2, where languagecode2 is the two-letter language code and country/regioncode2 is the two-letter subculture code. Examples include ja-JP for Japanese (Japan) and en-US for English (United States). In cases where a two-letter language code is not available, a three-letter code derived from ISO 639-2 is used.
Note that some culture names also specify an ISO 15924 script. For example, Cyrl specifies the Cyrillic script and Latn specifies the Latin script. A culture name that includes a script uses the pattern languagecode2-scripttag-country/regioncode2. An example of this type of culture name is uz-Cyrl-UZ for Uzbek (Cyrillic, Uzbekistan). On Windows operating systems before Windows Vista, a culture name that includes a script uses the pattern languagecode2-country/regioncode2-scripttag, for example, uz-UZ-Cyrl for Uzbek (Cyrillic, Uzbekistan).
A neutral culture is specified by only the two-letter lowercase language code. For example, fr specifies the neutral culture for French, and de specifies the neutral culture for German.
There are two culture names that contradict this rule. The cultures Chinese (Simplified), named zh-Hans, and Chinese (Traditional), named zh-Hant, are neutral cultures. The culture names represent the current standard and should be used unless you have a reason for using the older names zh-CHS and zh-CHT.
A culture identifier is a standard international numeric abbreviation and has the components necessary to uniquely identify one of the installed cultures. Your application can use predefined culture identifiers or define custom identifiers.
Certain predefined culture names and identifiers are used by this and other classes in the System.Globalization namespace. Detailed culture information appears in the tp://go.microsoft.com/fwlink/?LinkId=200048 at the Go Global Developer Center.
Remember that the culture names and identifiers represent only a subset of cultures that can be found on a particular computer. Windows versions or service packs can change the available cultures. Applications add custom cultures using the System.Globalization.CultureAndRegionInfoBuilder class. Users add their own custom cultures using the Microsoft Locale Builder tool. Microsoft Locale Builder is written in managed code using the CultureAndRegionInfoBuilder class.
Several distinct names are closely associated with a culture, notably the names associated with the following class members:
The cultures are generally grouped into three sets: invariant cultures, neutral cultures, and specific cultures.
An invariant culture is culture-insensitive. Your application specifies the invariant culture by name using an empty string ("") or by its identifier. CultureInfo.InvariantCulture defines an instance of the invariant culture. It is associated with the English language but not with any country/region. It is used in almost any method in the Globalization namespace that requires a culture.
A neutral culture is a culture that is associated with a language but not with a country/region. A specific culture is a culture that is associated with a language and a country/region. For example, fr is the neutral name for the French culture, and fr-FR is the name of the specific French (France) culture. Note that Chinese (Simplified) and Chinese (Traditional) are also considered neutral cultures.
Creating an instance of a System.Globalization.CompareInfo class for a neutral culture is not recommended because the data it contains is arbitrary. To display and sort data, specify both the language and region. Additionally, the CompareInfo.Name property of a System.Globalization.CompareInfo object created for a neutral culture returns only the country and does not include the region.
The defined cultures have a hierarchy in which the parent of a specific culture is a neutral culture and the parent of a neutral culture is the invariant culture. The CultureInfo.Parent property contains the neutral culture associated with a specific culture. Custom cultures should define the CultureInfo.Parent property in conformance with this pattern.
If the resources for a specific culture are not available in the operating system, the resources for the associated neutral culture are used. If the resources for the neutral culture are not available, the resources embedded in the main assembly are used. For more information on the resource fallback process, see Resource Fallback Process.
The list of locales in the Windows API is slightly different from the list of cultures supported by the .NET Framework. If interoperability with Windows is required, for example, through the p/invoke mechanism, the application should use a specific culture that is defined for the operating system. Use of the specific culture ensures consistency with the equivalent Windows locale, which is identified with a locale identifier that is the same as CultureInfo.LCID.
If DateTimeFormatInfo.Calendar is the System.Globalization.TaiwanCalendar but the System.Threading.Thread.CurrentCulture is not set to zh-TW, then DateTimeFormatInfo.NativeCalendarName, DateTimeFormatInfo.GetEraName(int), and DateTimeFormatInfo.GetAbbreviatedEraName(int) return an empty string ("").
In addition to the predefined cultures supported by the Windows operating system and the .NET Framework, the .NET Framework supports three types of custom cultures:
New cultures that supplement the cultures available in Windows or the .NET Framework. For example, an application could install a System.Globalization.CultureInfo object that represents the fj-FJ (or Fijan (Fiji)) culture on a system.
Replacement cultures whose properties are different from the properties of the standard cultures supported by Windows and the .NET Framework.
Standard cultures with user overrides. The user can use the Region and Language application in Control Panel to customize an existing culture's property values.
You can use the System.Globalization.CultureAndRegionInfoBuilder class to define, save, and register custom cultures that either supplement or replace existing cultures. The CultureAndRegionInfoBuilder.Save(string) method creates a Locale Data Markup Language (LDML) file that can be used to install a custom culture on target systems.
Because the .NET Framework supports custom cultures, you should consider the following when working with culture-specific data:
Custom cultures can have values that exceed the ranges of the predefined cultures. For example, some cultures have unusually long month names, unexpected date or time formats, or other unusual data.
When you display culture-specific data in the user interface, you should respect the user's customizations; for example, the user might want a 24-hour clock or a yyyyMMdd date format.
Remember that custom cultures override default values. Therefore, you cannot consider culture data to be stable. Country names, number and date formats, and spellings may change in the future. If you want to serialize culture-sensitive data such as date and time strings to be passed to the date and time parsing functions, you should use the invariant culture or a specific custom format string.
Except for the invariant culture, culture data is dynamic. This is true even for the predefined cultures. For example, countries or regions adopt new currencies, change their spellings of words, or change their preferred calendar, and culture definitions change to track this. Custom cultures are subject to change without notice, and any specific culture might be overridden by a custom replacement culture. Also, as discussed below, an individual user can override cultural preferences. Applications should always obtain culture data at run time.
When saving data, your application should use the invariant culture, a binary format, or a specific culture-independent format. Data saved according to the current values associated with a particular culture, other than the invariant culture, might become unreadable or might change in meaning if that culture changes.
When a new application thread is started, its current culture and current UI culture are defined by the current system culture, and not by the current thread culture. The following example illustrates the difference. It sets the current culture and current UI culture of an application thread to the French (France) culture (fr-FR). If the current culture is already fr-FR, the example sets it to the English (United States) culture (en-US). It displays three random numbers as currency values and then creates a new thread, which, in turn, displays three more random numbers as currency values. But as the output from the example shows, the currency values displayed by the new thread do not reflect the formatting conventions of the French (France) culture, unlike the output from the main application thread.
code reference: System.Globalization.CultureInfo.Class.Thread#1
In versions of the .NET Framework before the net_v45, the most common way to ensure that the main application thread shares the same culture with all other worker threads is to pass either the name of the application-wide culture or a System.Globalization.CultureInfo object that represents the application-wide culture to a System.Threading.ParameterizedThreadStart delegate. The following example uses this approach to ensure that the currency values displayed by two threads reflect the formatting conventions of the same culture.
code reference: System.Globalization.CultureInfo.Class.Thread#2
You can set the culture and UI culture of thread pool threads in a similar manner by calling the System.Threading.ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, object) method.
Starting with the net_v45, you can set the culture and UI culture of all threads in an application domain more directly by assigning a System.Globalization.CultureInfo object that represents that culture to the CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture properties. The following example uses these properties to ensure that all threads in the default application domain share the same culture.
code reference: System.Globalization.CultureInfo.Class.Thread#3
Although the CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture properties are static members, they define the default culture and default UI culture only for the application domain that is current at the time these property values are set. For more information, see the next section, Culture and Application Domains.
When you assign values to the CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture properties, the culture and UI culture of the threads in the application domain also change if they have not explicitly been assigned a culture. However, these threads reflect the new culture settings only while they execute in the current application domain. If these threads execute in another application domain, their culture becomes the default culture defined for that application domain. As a result, we recommend that you always set the culture of the main application thread, and not rely on the CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture properties to change it.
CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture are static properties that explicitly define a default culture only for the application domain that is current when the property value is set or retrieved. The following example sets the default culture and default UI culture in the default application domain to French (France), and then uses the AppDomainSetup class and the AppDomainInitializer delegate to set the default culture and UI culture in a new application domain to Russian (Russia). A single thread then executes two methods in each application domain. Note that the thread's culture and UI culture are not explicitly set; they are derived from the default culture and UI culture of the application domain in which the thread is executing. Note also that the CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture properties return the default System.Globalization.CultureInfo values of the application domain that is current when the method call is made.
code reference: System.Globalization.CultureInfo.Class.AppDomain#1
For more information about cultures and application domains, see Application Domains and Threads.
When a System.Globalization.CultureInfo object is serialized, all that is actually stored is CultureInfo.Name and CultureInfo.UseUserOverride. It is successfully de-serialized only in an environment where that CultureInfo.Name has the same meaning. The following three examples show why this is not always the case:
If the CultureInfo.CultureTypes property value is CultureTypes.WindowsOnlyCultures, and if that culture was first introduced in Windows Vista or a later version of the Windows operating system, it is not possible to de-serialize it on Windows XP. Similarly, if the culture was first introduced in Windows XP Service Pack 2, it is not possible to de-serialize it for a Windows XP system on which the culture has not been installed.
If the CultureInfo.CultureTypes value is CultureTypes.UserCustomCulture, and the computer on which it is de-serialized does not have this user custom culture installed, it is not possible to de-serialize it.
If the CultureInfo.CultureTypes value is CultureTypes.ReplacementCultures, and the computer on which it is de-serialized does not have this replacement culture, it de-serializes to the same name, but not all of the same characteristics. For example, if en-US is a replacement culture on computer A, but not on computer B, and if a System.Globalization.CultureInfo object referring to this culture is serialized on computer A and de-serialized on computer B, then none of the custom characteristics of the culture are transmitted. The culture de-serializes successfully, but with a different meaning.
The user might choose to override some of the values associated with the current culture of Windows through the regional and language options portion of Control Panel. For example, the user might choose to display the date in a different format or to use a currency other than the default for the culture. In general, your applications should honor these user overrides.
If CultureInfo.UseUserOverride is true and the specified culture matches the current culture of Windows, the System.Globalization.CultureInfo uses those overrides, including user settings for the properties of the System.Globalization.DateTimeFormatInfo instance returned by the CultureInfo.DateTimeFormat property, and the properties of the System.Globalization.NumberFormatInfo instance returned by the CultureInfo.NumberFormat property. If the user settings are incompatible with the culture associated with the System.Globalization.CultureInfo, for example, if the selected calendar is not one of the CultureInfo.OptionalCalendars, the results of the methods and the values of the properties are undefined.
The Spanish (Spain) culture has two culture identifiers: 0x0C0A, which uses the default international sort order, and 0x040A, which uses the traditional sort order. If the System.Globalization.CultureInfo is constructed using the es-ES culture name, the new System.Globalization.CultureInfo uses the default international sort order. For the traditional sort order, the object is constructed using the name es-ES_tradnl. For information on other cultures that have alternate sorts, see Using Alternate Sort Orders.