Global Development and Computing Portal Global Development and Computing Portal

Globalization Step-by-Step

Number Formatting

Currency FormattingAddresses
*
On This Page
Overview and DescriptionOverview and Description
Number Formatting in Win32Number Formatting in Win32
Number Formatting in Web PagesNumber Formatting in Web Pages
Number Formatting in .NET FrameworkNumber Formatting in .NET Framework
ReferencesReferences

Overview and Description

When dealing with numeric values, there are six major items to pay attention to:

1.

The character used as the thousands separator.
In the United States, this character is a comma (,). In Germany, it is a
period (.). Thus one thousand and twenty-five is displayed as 1,025
in the United States and 1.025 in Germany.
In Sweden, the thousands separator is a space.

2.

The character used as the decimal separator.
In the United States, this character is a period (.). In Germany, it is a
comma (,). Thus one thousand twenty-five and seven tenths is displayed
as 1,025.7 in the United States and 1.025,7 in Germany.

3.

The way negative numbers are displayed.
The negative sign can be used at the beginning of the number, but it
can also be used at the end of the number. Alternatively, the number can
be displayed with parentheses around it or even in a color such as red.
Thus a negative five hundred and twenty-seven could be displayed as:

4.

The shape of the numbers, or whether they have a one-to-one
correspondence to the decimal set of digits.

Numbers might, of course, be shaped differently from one locale to another.
Also, numbers in some locales might not correspond directly to the
digits (0-9) used in, say, the United States. (See Table 1 below)



Table 1: Digits used for English (United States), Arabic, and Japanese locales.

Table 1: Digits used for English (United States), Arabic, and Japanese locales.

Note how Japanese has one more digit than Arabic or English (United States). This represents the number 10.

5.

Digit grouping.
This refers to the number of digits contained between each separator for all digit groups that appear to the left of the decimal separator. For example, the 3-digit group is used for most cultures, such as for English (United States): 123,456,789.00. However, notice that Hindi uses a 2-digit grouping, except for the 3-digit grouping for denoting hundreds: 12,34,56,789.00

6.

The placement of the percent sign (%).
It can be written several ways: 98%, 98 %, 98 pct, %98. Thus you should never assume that you can hard-code the percent sign.

The user can define preferred number-formatting parameters by making selections from the Numbers tab of the Customize Regional Options property sheet, within the Regional And Language Options property sheet. (See Figure 1 below.)

Figure 1: Selecting the preferred number formatting.

Figure 1: Selecting the preferred number formatting.

Number Formatting in Win32

The easiest way to format numbers in a way that's locale-aware is to use the GetNumberFormat API. This API customizes the format of a number string for a specified locale. The following shows how the GetNumberFormat API is used to format a given number string for the current user locale (using the default settings for number formatting that the user has defined):

GetNumberFormat(LOCALE_USER_DEFAULT,	// locale (current user locale)
0,				// options
TEXT("1234567890.12345"),		// input string (see MSDN for legal
				// chars)
NULL,				// formatting information
g_szTemp,				// formatted string buffer
MAX_STR);				// size of buffer

For more advanced number formatting in the Win32 programming model, the GetLocaleInfo API can be used to retrieve most of the number-formatting parameters (such as thousands separators, decimal separators, and negative numbers). Here are the appropriate flags to use as LCType in your calls to GetLocaleInfo, in order to retrieve each one of the number-formatting parameters.

Thousands separator. LCType flag set to LOCALE_STHOUSAND

Decimal separator. LCType flag set to LOCALE_SDECIMAL

Negative numbers. LCType flag set to LOCALE_INEGNUMBER

Possible return values are shown in Table 2 below.

Table 2: Return values of various LCType flags.

Table 2: Return values of various LCType flags.

Native digits.LCType flag set to LOCALE_SNATIVEDIGITS. Here is a code sample that deals with native digits:

GetLocaleInfo(LOCALE_USER_DEFAULT,	// LCID (current user locale)
LOCALE_SNATIVEDIGITS,		// information type (native digits)
&g_szTemp,			// returned value
sizeof (g_szTemp));		// size of buffer

This code would produce the following result on English (US) and Farsi locales, respectively:

Figure 2: Native digits for English (US) and Farsi.

Figure 2: Native digits for English (US) and Farsi.

Digit Substitution. Digit substitution defines which set of digits (with its associated shapes) should be used for presenting numbers. This information can be retrieved with the LCType flag set to LOCALE_IDIGITSUBSTITUTION. The table below shows the possible return values:

Table 3: Return values of LOCALE_IDIGITSUBSTITUTION

Table 3: Return values of LOCALE_IDIGITSUBSTITUTION

Number Formatting in Web Pages

Earlier in "Use Locale Model", you saw how to retrieve the current browser locale on the client side and how to set the global locale of your context or session to this value. Once the appropriate locale has been set, you can easily format numbers by using FormatNumber, a locale-aware function.

With this function, formatting 123456.789 would become:

For English (United States)

123,456.789

For Arabic (Egypt)

١٢٣,٤٥٦.٧٨٩

Obviously the scripting technology does not offer the same flexibility to manipulate number formatting as NLS APIs do in the case of Win32 programming. However, the FormatNumber function enables you to display numbers according to the cultural format that the user prefers.

Number Formatting in .NET Framework

The NumberFormatInfo class defines how currency, decimal separators, and other numeric symbols are formatted and displayed based on culture. For example, the decimal number 10000.50 is formatted as 10,000.50 for the culture "en-US" and 10.000,50 for the culture "de-DE." An instance of NumberFormatInfo can be created for a specific cultureor the invariant culture, but not for a neutral culture. A neutral culture does not provide enough information to display the correct numeric format. Table 4-10 lists the standard format characters for each standard formatting pattern and the associated NumberFormatInfo property that can be set to modify this pattern.

Table 4: Standard format characters for basic formatting patterns and the associated NumberFormatInfo property used to modify these patterns.

Table 4: Standard format characters for basic formatting patterns and the associated NumberFormatInfo property used to modify these patterns.

The following code example displays an integer using the NumberFormatInfo standard currency format ("c") for the specified CurrentCulture.

using System.Globalization;

public class TestClass
{
   public static void Main()
   {
      int i = 100;
     
      // Create a CultureInfo object for English in Belize.
      CultureInfo bz = new CultureInfo("en-BZ");

      // Display i formatted as currency for bz.
      Console.WriteLine(i.ToString("c", bz));
     
      // Create a CultureInfo object for English in the U.S.
      CultureInfo us = new CultureInfo("en-US");
      // Display i formatted as currency for us.
      Console.WriteLine(i.ToString("c", us));

	// Create a CultureInfo object for Danish in Denmark.
	CultureInfo dk = new CultureInfo("da-DK");

      // Display i formatted as currency for dk.
      Console.WriteLine(i.ToString("c", dk));
   }
}

This code produces the following output:

$100.00
kr100,00

As when dealing with numbers, formatting conventions for addresses vary widely from one country to another. There are also discrepancies in the actual terms used when representing addresses that you will need to handle.

References

See MSDN documentation for the following APIS:

GetLocaleInfo

GetNumberFormat

LCType Constants

NumberFormatInfo

CurrentCulture

Currency FormattingAddresses
**
**