File: libc.info,  Node: The Elegant and Fast Way,  Prev: The Lame Way to Locale\ Data,  Up: Locale Information

Pinpoint Access to Locale Data
------------------------------

   When writing the X/Open Portability Guide the authors realized that
the `localeconv' function is not enough to provide reasonable access to
the locale information.  The information which was meant to be available
in the locale (as later specified in the POSIX.1 standard) requires more
possibilities to access it.  Therefore the `nl_langinfo' function was
introduced.

 - Function: char * nl_langinfo (nl_item ITEM)
     The `nl_langinfo' function can be used to access individual
     elements of the locale categories.  I.e., unlike the `localeconv'
     function which always returns all the information `nl_langinfo'
     lets the caller select what information is necessary.  This is very
     fast and it is no problem to call this function multiple times.

     The second advantage is that not only the numeric and monetary
     formatting information is available.  Also the information of the
     `LC_TIME' and `LC_MESSAGES' categories is available.

     The type `nl_type' is defined in `nl_types.h'.  The argument ITEM
     is a numeric values which must be one of the values defined in the
     header `langinfo.h'.  The X/Open standard defines the following
     values:

    `ABDAY_1'
    `ABDAY_2'
    `ABDAY_3'
    `ABDAY_4'
    `ABDAY_5'
    `ABDAY_6'
    `ABDAY_7'
          `nl_langinfo' returns the abbreviated weekday name.  `ABDAY_1'
          corresponds to Sunday.

    `DAY_1'
    `DAY_2'
    `DAY_3'
    `DAY_4'
    `DAY_5'
    `DAY_6'
    `DAY_7'
          Similar to `ABDAY_1' etc, but here the return value is the
          unabbreviated weekday name.

    `ABMON_1'
    `ABMON_2'
    `ABMON_3'
    `ABMON_4'
    `ABMON_5'
    `ABMON_6'
    `ABMON_7'
    `ABMON_8'
    `ABMON_9'
    `ABMON_10'
    `ABMON_11'
    `ABMON_12'
          The return value is abbreviated name for the month names.
          `ABMON_1' corresponds to January.

    `MON_1'
    `MON_2'
    `MON_3'
    `MON_4'
    `MON_5'
    `MON_6'
    `MON_7'
    `MON_8'
    `MON_9'
    `MON_10'
    `MON_11'
    `MON_12'
          Similar to `ABMON_1' etc but here the month names are not
          abbreviated.  Here the first value `MON_1' also corresponds
          to January.

    `AM_STR'
    `PM_STR'
          The return values are strings which can be used in the time
          representation which uses to American 1 to 12 hours plus
          am/pm representation.


          Please note that in locales which do not know this time
          representation these strings actually might be empty and
          therefore the am/pm format cannot be used at all.

    `D_T_FMT'
          The return value can be used as a format string for
          `strftime' to represent time and date in a locale specific
          way.

    `D_FMT'
          The return value can be used as a format string for
          `strftime' to represent a date in a locale specific way.

    `T_FMT'
          The return value can be used as a format string for
          `strftime' to represent time in a locale specific way.

    `T_FMT_AMPM'
          The return value can be used as a format string for
          `strftime' to represent time using the American-style am/pm
          format.

          Please note that if the am/pm format does not make any sense
          for the selected locale the returned value might be the same
          as the one for `T_FMT'.

    `ERA'
          The return value is value representing the eras of time used
          in the current locale.

          Most locales do not define this value.  An example for a
          locale which does define this value is the Japanese.  Here
          the traditional data representation is based on the eras
          measured by the reigns of the emperors.

          Normally it should not be necessary to use this value
          directly.  Using the `E' modifier for its formats the
          `strftime' functions can be made to use this information.
          The format of the returned string is not specified and
          therefore one should not generalize the knowledge about the
          representation on one system.

    `ERA_YEAR'
          The return value describes the name years for the eras of
          this locale.  As for `ERA' it should not be necessary to use
          this value directly.

    `ERA_D_T_FMT'
          This return value can be used as a format string for
          `strftime' to represent time and date using the era
          representation in a locale specific way.

    `ERA_D_FMT'
          This return value can be used as a format string for
          `strftime' to represent a date using the era representation
          in a locale specific way.

    `ERA_T_FMT'
          This return value can be used as a format string for
          `strftime' to represent time using the era representation in
          a locale specific way.

    `ALT_DIGITS'
          The return value is a representation of up to 100 values used
          to represent the values 0 to 99.  As for `ERA' this value is
          not intended to be used directly, but instead indirectly
          through the `strftime' function.  When the modifier `O' is
          used for format which would use numerals to represent hours,
          minutes, seconds, weekdays, months, or weeks the appropriate
          value for this locale values is used instead of the number.

    `INT_CURR_SYMBOL'
          This value is the same as returned by `localeconv' in the
          `int_curr_symbol' element of the `struct lconv'.

    `CURRENCY_SYMBOL'
    `CRNCYSTR'
          This value is the same as returned by `localeconv' in the
          `currency_symbol' element of the `struct lconv'.

          `CRNCYSTR' is a deprecated alias, still required by Unix98.

    `MON_DECIMAL_POINT'
          This value is the same as returned by `localeconv' in the
          `mon_decimal_point' element of the `struct lconv'.

    `MON_THOUSANDS_SEP'
          This value is the same as returned by `localeconv' in the
          `mon_thousands_sep' element of the `struct lconv'.

    `MON_GROUPING'
          This value is the same as returned by `localeconv' in the
          `mon_grouping' element of the `struct lconv'.

    `POSITIVE_SIGN'
          This value is the same as returned by `localeconv' in the
          `positive_sign' element of the `struct lconv'.

    `NEGATIVE_SIGN'
          This value is the same as returned by `localeconv' in the
          `negative_sign' element of the `struct lconv'.

    `INT_FRAC_DIGITS'
          This value is the same as returned by `localeconv' in the
          `int_frac_digits' element of the `struct lconv'.

    `FRAC_DIGITS'
          This value is the same as returned by `localeconv' in the
          `frac_digits' element of the `struct lconv'.

    `P_CS_PRECEDES'
          This value is the same as returned by `localeconv' in the
          `p_cs_precedes' element of the `struct lconv'.

    `P_SEP_BY_SPACE'
          This value is the same as returned by `localeconv' in the
          `p_sep_by_space' element of the `struct lconv'.

    `N_CS_PRECEDES'
          This value is the same as returned by `localeconv' in the
          `n_cs_precedes' element of the `struct lconv'.

    `N_SEP_BY_SPACE'
          This value is the same as returned by `localeconv' in the
          `n_sep_by_space' element of the `struct lconv'.


    `P_SIGN_POSN'
          This value is the same as returned by `localeconv' in the
          `p_sign_posn' element of the `struct lconv'.

    `N_SIGN_POSN'
          This value is the same as returned by `localeconv' in the
          `n_sign_posn' element of the `struct lconv'.

    `DECIMAL_POINT'
    `RADIXCHAR'
          This value is the same as returned by `localeconv' in the
          `decimal_point' element of the `struct lconv'.

          The name `RADIXCHAR' is a deprecated alias still used in
          Unix98.

    `THOUSANDS_SEP'
    `THOUSEP'
          This value is the same as returned by `localeconv' in the
          `thousands_sep' element of the `struct lconv'.

          The name `THOUSEP' is a deprecated alias still used in Unix98.

    `GROUPING'
          This value is the same as returned by `localeconv' in the
          `grouping' element of the `struct lconv'.

    `YESEXPR'
          The return value is a regular expression which can be used
          with the `regex' function to recognize a positive response to
          a yes/no question.

    `NOEXPR'
          The return value is a regular expression which can be used
          with the `regex' function to recognize a negative response to
          a yes/no question.

    `YESSTR'
          The return value is a locale specific translation of the
          positive response to a yes/no question.

          Using this value is deprecated since it is a very special
          case of message translation and this better can be handled
          using the message translation functions (*note Message
          Translation::.).

    `NOSTR'
          The return value is a locale specific translation of the
          negative response to a yes/no question.  What is said for
          `YESSTR' is also true here.

     The file `langinfo.h' defines a lot more symbols but none of them
     is official.  Using them is completely unportable and the format
     of the return values might change.  Therefore it is highly
     requested to not use them in any situation.

     Please note that the return value for any valid argument can be
     used for in all situations (with the possible exception of the
     am/pm time format related values).  If the user has not selected
     any locale for the appropriate category `nl_langinfo' returns the
     information from the `"C"' locale.  It is therefore possible to
     use this function as shown in the example below.

     If the argument ITEM is not valid the global variable ERRNO is set
     to `EINVAL' and a `NULL' pointer is returned.

   An example for the use of `nl_langinfo' is a function which has to
print a given date and time in the locale specific way.  At first one
might think the since `strftime' internally uses the locale information
writing something like the following is enough:

     size_t
     i18n_time_n_data (char *s, size_t len, const struct tm *tp)
     {
       return strftime (s, len, "%X %D", tp);
     }

   The format contains no weekday or month names and therefore is
internationally usable.  Wrong!  The output produced is something like
`"hh:mm:ss MM/DD/YY"'.  This format is only recognizable in the USA.
Other countries use different formats.  Therefore the function should
be rewritten like this:

     size_t
     i18n_time_n_data (char *s, size_t len, const struct tm *tp)
     {
       return strftime (s, len, nl_langinfo (D_T_FMT), tp);
     }

   Now the date and time format which is explicitly selected for the
locale in place when the program runs is used.  If the user selects the
locale correctly there should never be a misunderstanding over the time
and date format.



