2
0
Просмотр исходного кода

[ZF-7359] Zend_Locale/Zend_Currency:

- fixed a PHP bug with autoconversion
  see http://bugs.php.net/bug.php?id=43053 for details
- added support for scientific numbers to Zend_Locale_Format

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@16998 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 лет назад
Родитель
Сommit
ec2bc6d026

+ 1 - 1
library/Zend/Currency.php

@@ -138,7 +138,7 @@ class Zend_Currency
         // Format the number
         $format = $options['format'];
         $locale = $this->_locale;
-        if (empty($format) === true) {
+        if (empty($format)) {
             $format = Zend_Locale_Data::getContent($this->_locale, 'currencynumber');
         } else if (Zend_Locale::isLocale($format, true, false)) {
             $locale = $format;

+ 31 - 1
library/Zend/Locale/Format.php

@@ -293,6 +293,7 @@ class Zend_Locale_Format
         require_once 'Zend/Locale/Math.php';
 
         $value             = Zend_Locale_Math::normalize($value);
+        $value             = self::_floatalize($value);
         $options           = self::_checkOptions($options) + self::$_options;
         $options['locale'] = (string) $options['locale'];
 
@@ -511,7 +512,7 @@ class Zend_Locale_Format
      * @param  string $type
      * @return string
      */
-    public static function _getRegexForType($type, $options)
+    private static function _getRegexForType($type, $options)
     {
         $decimal  = Zend_Locale_Data::getContent($options['locale'], $type);
         $decimal  = preg_replace('/[^#0,;\.\-Ee]/', '',$decimal);
@@ -607,6 +608,35 @@ class Zend_Locale_Format
     }
 
     /**
+     * Internal method to convert a scientific notation to float
+     * Additionally fixed a problem with PHP <= 5.2.x with big integers
+     *
+     * @param string $value
+     */
+    private static function _floatalize($value)
+    {
+        $value = strtoupper($value);
+        if (strpos($value, 'E') === false) {
+            return $value;
+        }
+
+        $number = substr($value, 0, strpos($value, 'E'));
+        if (strpos($number, '.') !== false) {
+            $post   = strlen(substr($number, strpos($number, '.') + 1));
+            $mantis = substr($value, strpos($value, 'E') + 1);
+            if ($mantis < 0) {
+                $post += abs((int) $mantis);
+            }
+
+            $value = number_format($value, $post, '.', '');
+        } else {
+            $value = number_format($value, 0, '.', '');
+        }
+
+        return $value;
+    }
+
+    /**
      * Alias for getNumber
      *
      * @param   string  $value    Number to localize

+ 10 - 0
tests/Zend/CurrencyTest.php

@@ -605,4 +605,14 @@ class Zend_CurrencyTest extends PHPUnit_Framework_TestCase
         $currency = new Zend_Currency(null, 'en_US');
         $this->assertEquals('-$74.9500', $currency->toCurrency(-74.95, array('currency' => 'USD', 'precision' => 4)));
     }
+
+    /**
+     * @see ZF-7359
+     */
+    public function testPHPsScientificBug()
+    {
+        $currency = new Zend_Currency("USD", "en_US");
+        $this->assertEquals('$0.00', $currency->toCurrency(1.0E-4));
+        $this->assertEquals('$0.00', $currency->toCurrency(1.0E-5));
+    }
 }

+ 14 - 0
tests/Zend/Locale/FormatTest.php

@@ -1018,4 +1018,18 @@ class Zend_Locale_FormatTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(14, $value['minute']);
         $this->assertEquals(55, $value['second']);
     }
+
+    /**
+     * Tests conversion from scientific numbers to decimal notation
+     */
+    public function testScientificNumbers()
+    {
+        $this->assertEquals(   '0,0', Zend_Locale_Format::toNumber(  1E-2, array('precision' => 1, 'locale' => 'de_AT')));
+        $this->assertEquals(   '0,0100', Zend_Locale_Format::toNumber(  1E-2, array('precision' => 4, 'locale' => 'de_AT')));
+        $this->assertEquals(   '100,0', Zend_Locale_Format::toNumber(  1E+2, array('precision' => 1, 'locale' => 'de_AT')));
+        $this->assertEquals(   '100,0000', Zend_Locale_Format::toNumber(  1E+2, array('precision' => 4, 'locale' => 'de_AT')));
+        $this->assertEquals(   '0', Zend_Locale_Format::toNumber(  1E-5, array('precision' => 0, 'locale' => 'de_AT')));
+        $this->assertEquals(   '0,00001', Zend_Locale_Format::toNumber(  1.3E-5, array('precision' => 5, 'locale' => 'de_AT')));
+        $this->assertEquals(   '0,000013', Zend_Locale_Format::toNumber(  1.3E-5, array('precision' => 6, 'locale' => 'de_AT')));
+    }
 }