# The Locale Data Structure

The Locale data structure is like a little data base the system provides. Once you get a pointer to the Locale structure, it has, among other things, the current language being used, the country code, and the format of dates for the user's cultural environment.

The system creates a Locale structure when an application calls `intlOpenLocale()`. `intlOpenLocale()` returns an `Item`, which must be disposed of using the `intlCloseLocale()` macro.

To examine the contents of the Locale structure, an application calls `intlLookupLocale(),` which returns a pointer to the Locale structure for the specified `Item`. The definition of the Locale structure is shown below.

``

    typedef struct Locale
    {
        ItemNode          loc_Item;              /* system linkage */

        /* prefered language to use */
        LanguageCodes     loc_Language;

        /* An array of dialects for the current language, listed in order
         * of preference, and terminated with INTL_DIALECTS_ARRAY_END
         */
        DialectCodes     *loc_Dialects;

        /* ISO-3166 numeric-3 code for the user's country */
        CountryCodes      loc_Country;

        /* general description of the user's environment */
         int32             loc_GMTOffset;     /* minutes from GMT */
        MeasuringSystems  loc_MeasuringSystem; /* measuring system to use */
        CalendarTypes     loc_CalendarType;   /* calendar type to use */
        DrivingTypes      loc_DrivingType;    /* side of the street */

        /* number formatting */
        NumericSpec       loc_Numbers;
        NumericSpec       loc_Currency;
        NumericSpec       loc_SmallCurrency;

        /* date formatting */
        DateSpec          loc_Date;
        DateSpec          loc_ShortDate;
        DateSpec          loc_Time;
        DateSpec          loc_ShortTime;
    } Locale;

The fields in the `Locale` structure are as follows:

- `loc_Item` provides system linkage for Locale structures which are allocated in system space so that they can be shared among multiple applications.

- `loc_Language` defines the language to use within an application. Each supported language has a code, which is taken from the ISO 639 Standard.

- `loc_Dialects` is a pointer to an array of dialects. Regional variations within a given language are accommodated through dialect tables, which are an array of dialect codes, terminated by `INTL_DIALECT_ARRAY_END`.

- The dialects appear in the array in decreasing order of user preference. For example, if the language is `INTL_LANG_ENGLISH`, then the dialect array could hold `INTL_ED_AMERICAN`, `INTL_ED_AUSTRALIAN`, `INTL_ED_BRITISH`, and so on.

- `loc_Country` contains the standard international country code for the current country. These codes are taken from the ISO 3166 Standard.

- `loc_GMTOffset` contains the offset in minutes of the current location relative to the standard GMT reference point.

- `loc_MeasuringSystem` indicates the measuring system to use. This can be `INTL_MS_METRIC`, `INTL_MS_AMERICAN`, or `INTL_MS_IMPERIAL`.

- `loc_CalendarType` indicates what type of calendar to use. This can be the traditional Gregorian calendar, with either Monday or Sunday as the first day of the week, or it can be the Arabic, Jewish, or Persian calendar.

- `loc_DrivingType` indicates on which side of the street cars usually travel in the current country.

- `loc_Numbers`, `loc_Currency`, `loc_SmallCurrency` specifies how to format numbers and currency. The `NumericSpec` structure contains the necessary information to properly localize number output and input. These three `NumericSpec` structures can be passed directly to the `intlFormatNumber()` function to apply localized formatting.

- `loc_Date`, `loc_ShortDate`, `loc_Time`, `loc_ShortTime` specifies how to format dates and time. The DateSpec array contains the necessary information needed to properly localize date and time output and input. These four `DateSpec` arrays can be passed directly to the `intlFormatDate()` function to apply localized formatting.

## NumericSpec Structure

Each culture has its own way of writing numbers and currency. The Locale structure contains three NumericSpec structures that contain number and currency formatting specifications and are used to produce correctly localized output for the target cultures.

The NumericSpec structure defines how numbers should be formatted. It is sufficiently flexible to cover plain numbers and currency values. The structure is shown below.

``

    typedef struct NumericSpec
    {
      /* how to generate a positive number */
      GroupingDesc  ns_PosGroups;  /* grouping description */
      unichar      *ns_PosGroupSep;  /* separates the groups */
      unichar      *ns_PosRadix;    /* decimal mark         */
      GroupingDesc  ns_PosFractionalGroups; /* grouping description */
      unichar      *ns_PosFractionalGroupSep; /* separates the groups */
      unichar      *ns_PosFormat;           /* for post-processing  */
      uint32               ns_PosMinFractionalDigits; /* min # of frac digits */
      uint32       ns_PosMaxFractionalDigits; /* max # of frac digits */

      /* how to generate a negative number */
      GroupingDesc  ns_NegGroups;   /* grouping description */
      unichar      *ns_NegGroupSep; /* separates the groups */
      unichar      *ns_NegRadix;   /* decimal mark        */
      GroupingDesc  ns_NegFractionalGroups;   /* grouping description */
      unichar      *ns_NegFractionalGroupSep;  /* separates the groups */
      unichar      *ns_NegFormat;              /* for post-processing  */
      uint32       ns_NegMinFractionalDigits; /* min # of frac digits */
      uint32       ns_NegMaxFractionalDigits; /* max # of frac digits */

      /* when the number is zero, this string is used 'as-is' */
      unichar          *ns_Zero;
    } NumericSpec;

Using the fields in the NumericSpec structure, the `intlFormatNumber()` function can correctly format numbers and currency according to local rules and customs. The fields of the NumericSpec structure are as follows:

- `ns_PosGroups` defines how digits are grouped left of the decimal mark. An `EgroupingDesc` is a 32-bit bitfield in which every ON bit in the bitfield indicates a separator sequence should be inserted after the associated digit. If bit 0 is ON, the grouping separator is inserted after digit 0 of the formatted number.

- `ns_PosGroupSep` is a string that separates groups of digits to the left of the decimal mark.

- `ns_PosRadix` is a string used as a decimal character.

- `ns_PosFractionalGroups` is a `GroupingDesc` array that defines how digits are grouped to the right of the decimal character.

- `ns_PosFractionalGroupSep` is a string used to separate groups of digits to the right of the decimal mark.

- `ns_PosFormat` is used for post-processing on a formatted number. Typically it is used to add currency notation around a numeric value. The string in this field is used as a format string in `sprintf()`, and the formatted numeric value is also a parameter to `sprintf()`.

For example, if `ns_PosFormat` is defined as $%s, and the formatted numeric value is 0.02. The result of the post-processing will be $0.02. When this field is NULL, no post-processing occurs.

- `ns_PosMinFractionalDigits` specifies the minimum number of characters to the right of the decimal mark. If there are fewer characters than the minimum, the number is padded with 0s.

- `ns_PosMaxFractionalDigits` specifies the maximum number of characters to the right of the decimal mark. If there are more characters than the maximum, the string is truncated.

- `ns_NegGroups` is similar to `ns_PosGroups`, except it specifies negative numbers`.`

- `ns_NegGroupSep` is `similar to` `ns_PosGroupSep` `but for negative numbers.`

- `ns_NegRadix` `is similar to` `ns_PosRadix` `except it specifies negative numbers.`

- `ns_NegFractionalGroups` `is similar to` `ns_PosFractionalGroups``, except it specifies negative numbers.`

- `ns_NegFractionalGroupSep` is similar to `ns_PosFractionalGroupSep,`except it specifies negative numbers.

- `ns_NegFormat` `similar to` `ns_PosFormat``, except it specifies negative numbers.`

- `ns_NegMinFractionalDigits` is similar to `ns_PosMinFractionalDigits`, `except it specifies` negative numbers.

- `ns_NegMaxFractionalDigits` is similar to `ns_PosMaxFractionalDigits`, `except it specifies` negative numbers.

- `ns_Zer` If the number being processed is 0, then this string pointer is used as is and is copied directly into the resulting buffer. If this field is NULL, then the number is formatted as if it were a positive number.

Typically, an application doesn't have to deal with the interpretation of a NumericSpec structure. The Locale structure contains three NumericSpec structures initialized with the correct information for the target culture, which can be passed to `intlFormatNumber()` to convert numbers into string form.

## DateSpec Arrays

Dates also vary in format across different cultures. The Locale structure contains four `DateSpec` arrays which define the local formats for date and time representation.

The `DateSpec` arrays contain format commands similar to `printf()` format strings. The% commands are inserted in the formatting string to produce custom date output. An application can provide the `DateSpec` structure from the Locale structure to the `intlFormatDate()` function or it can create its own DateSpec structures for custom formatting.