From c26f4bced87e3208105666e9fcd847d5b29dc6e2 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Tue, 17 Sep 2013 23:24:10 +0200 Subject: NumberFormat: force the use of C locale when formatting numbers. Add some testcases. Fixes #486 --- framework/I18N/core/NumberFormat.php | 71 +++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 22 deletions(-) (limited to 'framework') diff --git a/framework/I18N/core/NumberFormat.php b/framework/I18N/core/NumberFormat.php index 25af6846..ded64782 100644 --- a/framework/I18N/core/NumberFormat.php +++ b/framework/I18N/core/NumberFormat.php @@ -115,12 +115,17 @@ class NumberFormat */ function format($number, $pattern='d', $currency='USD', $charset='UTF-8') { + $oldLocale=setLocale(LC_NUMERIC, '0'); + setlocale(LC_NUMERIC, 'C'); + $this->setPattern($pattern); if(strtolower($pattern) == 'p') - $number = $number * 100.0; + $number = $number * 100; + + $string = (string)$number; - $decimal = $this->formatDecimal($number); + $decimal = $this->formatDecimal($string); $integer = $this->formatInteger(abs($number)); if(strlen($decimal)>0) @@ -147,6 +152,8 @@ class NumberFormat $result = str_replace('ยค',$symbol, $result); + setlocale(LC_NUMERIC, $oldLocale); + return I18N_toEncoding($result, $charset); } @@ -155,17 +162,17 @@ class NumberFormat * @param string the decimal number in string form. * @return string formatted integer string with grouping */ - protected function formatInteger($number) + protected function formatInteger($string) { - $decimalDigits = $this->formatInfo->DecimalDigits; - $string = (string)intval(round($number,$decimalDigits)); + $string = (string)$string; + $decimalDigits = $this->formatInfo->DecimalDigits; //if not decimal digits, assume 0 decimal points. - //if(is_int($decimalDigits) && $decimalDigits > 0) - // $string = (string)round(floatval($string),$decimalDigits); - //$dp = strpos($string, '.'); - //if(is_int($dp)) - // $string = substr($string, 0, $dp); + if(is_int($decimalDigits) && $decimalDigits > 0) + $string = (string)round(floatval($string),$decimalDigits); + $dp = strpos($string, '.'); + if(is_int($dp)) + $string = substr($string, 0, $dp); $integer = ''; $digitSize = $this->formatInfo->getDigitSize(); @@ -228,23 +235,43 @@ class NumberFormat * @param string the decimal number in string form. * @return string formatted decimal places. */ - protected function formatDecimal($number) + protected function formatDecimal($string) { - $decimalDigits = $this->formatInfo->DecimalDigits; - $decimalSeparator = $this->formatInfo->DecimalSeparator; + $dp = strpos($string, '.'); $decimal = ''; - if ($decimalDigits > 0) { - //do the correct rounding here - $number = round(floatval($number), $decimalDigits); - $decimal = substr((string)$number,strlen((string)intval($number))+1 ); - $decimal = $decimalSeparator.str_pad($decimal,$decimalDigits,'0',STR_PAD_RIGHT); + $decimalDigits = $this->formatInfo->DecimalDigits; + $decimalSeparator = $this->formatInfo->DecimalSeparator; - } elseif($decimalDigits == -1) { - $decimal = $decimalSeparator.substr((string)$number,strlen((string)intval($number))+1 ); - } elseif($decimalDigits == false) - $decimal = $decimalSeparator.substr((string)$number,strlen((string)intval($number))+1 ); + //do the correct rounding here + //$string = round(floatval($string), $decimalDigits); + if(is_int($dp)) + { + if($decimalDigits == -1) + { + $decimal = substr($string, $dp+1); + } + else if(is_int($decimalDigits)) + { + $float = round((float)$string, $decimalDigits); + if(strpos((string)$float, '.') === false) + { + $decimal = str_pad($decimal,$decimalDigits,'0'); + } + else + { + $decimal = substr($float, strpos($float,'.')+1); + if(strlen($decimal)<$decimalDigits) + $decimal = str_pad($decimal,$decimalDigits,'0'); + } + } + else + return $decimal; + return $decimalSeparator.$decimal; + } + else if ($decimalDigits > 0) + return $decimalSeparator.str_pad($decimal,$decimalDigits,'0'); return $decimal; } -- cgit v1.2.3