Book HomePHP CookbookSearch this book

16.7. Localizing Currency Values

16.7.1. Problem

You want to display currency amounts in a locale-specific format.

16.7.2. Solution

Use the pc_format_currency( ) function, shown in Example 16-1, to produce an appropriately formatted string. For example:

setlocale(LC_ALL,'fr_CA');
print pc_format_currency(-12345678.45);
(12 345 678,45 $)

16.7.3. Discussion

The pc_format_currency( ) function, shown in Example 16-1, gets the currency formatting information from localeconv( ) and then uses number_format( ) and some logic to construct the correct string.

Example 16-1. pc_format_currency

function pc_format_currency($amt) {
    // get locale-specific currency formatting information 
    $a = localeconv();
    
    // compute sign of $amt and then remove it
    if ($amt < 0) { $sign = -1; } else { $sign = 1; }
    $amt = abs($amt);
    // format $amt with appropriate grouping, decimal point, and fractional digits 
    $amt = number_format($amt,$a['frac_digits'],$a['mon_decimal_point'],
                         $a['mon_thousands_sep']);
    
    // figure out where to put the currency symbol and positive or negative signs
    $currency_symbol = $a['currency_symbol'];
    // is $amt >= 0 ? 
    if (1 == $sign) {
        $sign_symbol  = 'positive_sign';
        $cs_precedes  = 'p_cs_precedes';
        $sign_posn    = 'p_sign_posn';
        $sep_by_space = 'p_sep_by_space';
    } else {
        $sign_symbol  = 'negative_sign';
        $cs_precedes  = 'n_cs_precedes';
        $sign_posn    = 'n_sign_posn';
        $sep_by_space = 'n_sep_by_space';
    }
    if ($a[$cs_precedes]) {
        if (3 == $a[$sign_posn]) {
            $currency_symbol = $a[$sign_symbol].$currency_symbol;
        } elseif (4 == $a[$sign_posn]) {
            $currency_symbol .= $a[$sign_symbol];
        }
        // currency symbol in front 
        if ($a[$sep_by_space]) {
            $amt = $currency_symbol.' '.$amt;
        } else {
            $amt = $currency_symbol.$amt;
        }
    } else {
        // currency symbol after amount 
        if ($a[$sep_by_space]) {
            $amt .= ' '.$currency_symbol;
        } else {
            $amt .= $currency_symbol;
        }
    }
    if (0 == $a[$sign_posn]) {
        $amt = "($amt)";
    } elseif (1 == $a[$sign_posn]) {
        $amt = $a[$sign_symbol].$amt;
    } elseif (2 == $a[$sign_posn]) {
        $amt .= $a[$sign_symbol];
    }
    return $amt;

The code in pc_format_currency( ) that puts the currency symbol and sign in the correct place is almost identical for positive and negative amounts; it just uses different elements of the array returned by localeconv( ). The relevant elements of localeconv( )'s returned array are shown in Table 16-1.

Table 16-1. Currency-related information from localeconv( )

Array element

Description

currency_symbol

Local currency symbol

mon_decimal_point

Monetary decimal point character

mon_thousands_sep

Monetary thousands separator

positive_sign

Sign for positive values

negative_sign

Sign for negative values

frac_digits

Number of fractional digits

p_cs_precedes

1 if currency_symbol should precede a positive value, 0 if it should follow

p_sep_by_space

1 if a space should separate the currency symbol from a positive value, 0 if not

n_cs_precedes

1 if currency_symbol should precede a negative value, 0 if it should follow

n_sep_by_space

1 if a space should separate currency_symbol from a negative value, 0 if not

p_sign_posn

Positive sign position:

 
  • 0if parenthesis should surround the quantity and currency_symbol

  • 1 if the sign string should precede the quantity and currency_symbol

  • 2 if the sign string should follow the quantity and currency_symbol

  • 3 if the sign string should immediately precede currency_symbol

  • 4 if the sign string should immediately follow currency_symbol

n_sign_posn

Negative sign position: same possible values as p_sign_posn

There is a function in the C library called strfmon( ) that does for currency what strftime( ) does for dates and times; however, it isn't implemented in PHP. The pc_format_currency( ) function provides most of the same capabilities.

16.7.4. See Also

Section 2.10 also discusses number_format( ); documentation on localeconv( ) at http://www.php.net/localeconv and number_format( ) at http://www.php.net/number-format.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.