Use locale-provided values

Some commonly needed values and translated messages are usually already translated and provided with the locale. These values include everything from common date and time formats to separators used for numeric output to the full and abbreviated month names and week days and much more. Please see langinfo.h for a full list.

Make use of these values whenever possible instead of marking them for translation in your application. It's not only unnecessary to translate these values again, but if you use the locale-provided values, the locale system is properly used. Everything is not dependant on the user using a particular translation -- as an example, the user can opt to have the interface displayed in American English if he or she is more comfortable with that, but still have time values displayed in another locale format, and this will automatically work.

Please always check if the localized setting you want is provided with the locales or if you can use such an approach before using a solution where you mark such values for translation in your application.

Also use international standards when you design default values that are used if the locales or a particular locale doesn't provide the information you want. As an example, default to A4 paper sizes (ISO 216), metric units, degrees centigrade, and the standardized date and time formats (ISO 8601). This will ensure that users around the world will have a fair chance of being provided with defaults that are familiar to them. Specifically, avoid using Letter, feet, degrees Fahrenheit or the US date format or 12-hour clock by default. These values are not only not international standards, they are also in many cases ambigious and not well understood in most parts of the world. Remember that also the C locale specifies use of metric units, A4 paper size and the ISO time format. Other values that are more familiar to US residents should be provided by the en_US locale.

To give an example of this, let's consider a printer dialog that lets the user chose between "A4", "Letter" and "Custom" paper formats. But what should be selected as the default? A good strategy is to follow this scheme:

  1. Use the value that the user used last time as the default.
  2. If that fails (if for example the user hasn't used this dialog before), use the value that is provided by the locale's paper format setting.
  3. If that fails (if for example this value isn't provided by the user's locale and you need a fallback), use the internationally standardized value (in this case "A4") as the default.

Below are some examples of how to use locale-provided values. This one gets the paper size (thanks to Ulrich Drepper for the code):

   #define _GNU_SOURCE
   #include <langinfo.h>
   #include <locale.h>
   int main (void)
   {
     int height;
     int width;
     setlocale (LC_ALL, "");
     height = (int) (long int) nl_langinfo (_NL_PAPER_HEIGHT);
     width = (int) (long int) nl_langinfo (_NL_PAPER_WIDTH);
     if (height == 297 && width == 210)
       puts ("A4");
     else if (height == 279 && width == 216)
       puts ("US letter");
     else
       printf ("paper format with height %dmm and width %dmm\n", height, width);
     return 0;
   }

The example below shows how to get the currency symbol from the locale.

   #define _GNU_SOURCE
   #include <langinfo.h>
   #include <locale.h>
   #include <stdio.h>
   int main (void)
   {
     setlocale (LC_ALL, "");
     puts (nl_langinfo (_NL_MONETARY_DUO_CURRENCY_SYMBOL));
     /* Alternatively, __CURRENCY_SYMBOL can be used above. */
     return 0;
   }

This example displays the language and country information specified in the user's locale.

   #define _GNU_SOURCE
   #include <langinfo.h>
   #include <locale.h>
   #include <stdio.h>
   int main (void)
   {
     setlocale (LC_ALL, "");
     puts (nl_langinfo (_NL_IDENTIFICATION_LANGUAGE));
     puts (nl_langinfo (_NL_IDENTIFICATION_TERRITORY));
     return 0;
   }

This example prints the locale's preferred time format and the short and long names of Monday.

   #define _GNU_SOURCE
   #include <langinfo.h>
   #include <locale.h>

   int main (void)
   {
     setlocale (LC_ALL, "");
     puts (nl_langinfo (D_FMT));
     puts (nl_langinfo (ABDAY_2));
     puts (nl_langinfo (DAY_2));
     return 0;
   }

The last example below prints the decimal character and thousands separator used by the locale, and prints some numbers formatted according to the locale's settings.

   #define _GNU_SOURCE
   #include <langinfo.h>
   #include <locale.h>
   #include <stdio.h>

   int main (void)
   {
     setlocale (LC_ALL, "");
     puts (nl_langinfo (__DECIMAL_POINT));
     puts (nl_langinfo (__THOUSANDS_SEP));
     /* Print some numbers formatted with the locale's decimal character and
        thousands separator. */
     printf ("%'.2f\n", 9876543210.0123456789);
     printf ("%'d\n", 876543210);
     return 0;
   }

TranslationProject/DevGuidelines/Use locale-provided values (last edited 2008-02-03 14:44:31 by anonymous)