Custom Locales vs Custom Cultures in Windows Vista / .Net Framework

When a Custom Culture is created in .Net it is used by Vista as well as a Custom Locale.  There are some disparities between the data available to the Framework and the Windows OS, causing a few edge cases. Additionally some information is available in a shipped locale that the .Net Framework cannot currently modify.  There are 3 groups of unusual data items: Those that are not available in the CultureAndRegionInfoBuilder but are exposed in the LDML and those that cannot be changed or created in a custom culture. amd those that behave slightly differently than normal locales.

Fields that cannot be created in a Custom Locale:

  • Native Calendar Names - The .Net Framework does not currently provide a method for specifying Native Calendar Names, so those are unavailable to a custom locale and the defaults will be used.  This is most obvious in intl.cpl in the list of available calendars for a locale.  Calendar names are instead provided a default for each calendar.
  • Language Names - The .Net Framework does not have "Language" name fields as retrieved by GetLocaleInfo(LOCALE_SENGLANGUAGE), so that data is duplicated from the Display Name.

Fields with behavior that differs from a built in locale

  •  GetLocaleInfo(LOCALE_SLANGUAGE) typically retrieves a localized name from the resource field for the current UI language.  Since Custom Locales cannot specify a name for each of the thousands of languages, LOCALE_SLANGUAGE will cause the locale's native display name to be used, unless the UI language is English, in which case the locale's English display name will be used.

Fields that can only be changed in the LDML, but do not have properties in the CultureAndRegionInfoBuilder:

  • msLocale:durationFormats - Windows Vista introduces GetDurationFormat() for formatting time durations.  This section of the LDML file allows for customization of those formats.  The format of this section is similar to the msLocale:timeFormatLength sections
  • paperSize - this is a standard LDML property and can be used to set the windows paper size for GetLocaleInfoEx(LOCALE_SPAPERSIZE)
  • msLocale:fontSignature - provides data used by Windows to determine likely unicode code points used by this locale and the oem and ansi code pages that would apply to this locale.  I'd suggest copying the value from a similar locale.  Ie: if you're making a CJK locale then copy the values from one of the other CJK pages.  This is only used to help windows optimize some character information and custom locales should still work even if this information isn't perfect.
  • msLocale:leadingZero - This is not used by the Framework, but impacts number formatting in Windows
  • msLocale:scripts - This is a list of 4 letter script codes expected for this language.  Examples would be Latn; or Cyrl;Latn;.  Each script is followed by a semi-colon.
  • msLocale:englishLanguage - this is the name of the locale in English.
  • msLocale:countryCode - A numeric code similar to the international dialing code.  Data provided for the Windows GetLocaleInfoEx(LOCALE_ICOUNTRY).

Try dumping an LDML file for an existing culture by doing something like this:

     CultureAndRegionInfoBuilder carib = new CultureAndRegionInfoBuilder("en-US", CultureAndRegionModifiers.Replacement);
     carib.Save("en-US.ldml");

Examining the resulting LDML can help understand how the values are represented.  The Unicode LDML information is also helpful, but won't help for the msLocale tags.  I'll blog some more when there's more information about the LDML file output by the CARIB.