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.6. Localizing Dates and Times |  | 16.8. Localizing Images |
Copyright © 2003 O'Reilly & Associates. All rights reserved.
|
|