number_format() doesn't accept thousands separator longer than 1 char (returns an unknown char: �). See this php.net comment and the above one.

This patch wraps number_format() in str_replace() to solve the problem, and also changes preg_replace() to substr() at "decimal counting".

Comments

markus_petrux’s picture

Version: 6.x-1.3 » 6.x-1.x-dev
Status: Needs review » Needs work

hmm... the problem with multiple byte characters may also happen with the decimal point. For some reason I thought I fixed this, but it seems I forgot to do it. :(

Well, try this code to see how it can also fail with decimal points:

$number = 12345467.89;
$decimal_points = array(
  "\x2E" => t('full stop (.)'),
  "\x2C" => t('comma (,)'),
  "\xD9\xAB" => t('arabic decimal separator (٫)'),
);
$thousands_seps = array(
  '' => t('none'),
  "\x2E" => t('full stop (.)'),
  "\x2C" => t('comma (,)'),
  "\x27" => t("apostrophe (')"),
  "\xC2\xA0" => t('no-break space ( )'),
  "\xEF\xBC\x8C" => t('full width comma (,)'),
  "\xD9\xAC" => t('arabic thousands separator (٬)'),
  "\xE1\x8B\x88" => t('ethiopic syllable wa (ወ)'),
);
print '<table><tr><th></th>';
foreach ($decimal_points as $decimal_point_char => $decimal_point_name) {
  print '<th style="text-align:right">'. $decimal_point_name .'</th>';
}
print '</tr>';
foreach ($thousands_seps as $thousands_sep_char => $thousands_sep_name) {
  print '<tr>';
  print '<td style="text-align:right">'. $thousands_sep_name .'</td>';
  foreach ($decimal_points as $decimal_point_char => $decimal_point_name) {
    $str1 = number_format($number, 2, $decimal_point_char, $thousands_sep_char); // This one fails!
    $str2 = str_replace(array('X', 'Z'), array($decimal_point_char, $thousands_sep_char), number_format($number, 2, 'X', 'Z'));
    print '<td style="text-align:right">'. $str1 .'<br />'. $str2 .'</td>';
  }
  print '</tr>';
}
print '</table>';

Your change in the way decimal places are counted does not work because it counts trailing zeros to the right of the decimal part. That's why I used preg_replace.

Try this to see what I mean:

$numbers = array(
  123456789,
  12345678.9,
  1234567.89,
  123456.789,
  12345.6789,
  1234.56789,
  123.456789,
  12.3456789,
  1.23456789,
  .123456789,
);
foreach ($numbers as $number) {
  $number = sprintf('%f', (float)$number);
  $decimals = (($pos = strpos($number, '.')) === FALSE ? 0 : strlen($number) - $pos - 1);
  print $number .' -&gt; '. $decimals ."<br />";
}
markus_petrux’s picture

Title: number_format() thousands separator "bug" » number_format() problems with multibyte characters used as decimail point and/or thousands separators
Status: Needs work » Needs review
StatusFileSize
new776 bytes

Could you please try this one?

markus_petrux’s picture

StatusFileSize
new971 bytes

Oops! Another patch, that also fixes an issue than may happen when the input number in an integer but -1 is passed to display a variable number of decimal places.

xmarket’s picture

StatusFileSize
new1.77 KB

I did a few thousand test during the development of my length converter and I suggest the attached patch.

markus_petrux’s picture

Status: Needs review » Fixed

Commited to CVS, with slight variations. Thanks

markus_petrux’s picture

Status: Fixed » Closed (fixed)