ZF-11641: Zend_Currency converts 1 to 10 EUR if LC_ALL is set to de_DE



I got the following Problem: If i call $this->currency(1) in a View-Script, it returns: '10,00 €' (which is obviously wrong, expected: '1,00 €'). If i change the locale-settings (see below for more Information) to en_US, $this->currency(1) returns '1,00 $' (which is good but i dont need USD).

If i remove the follwing line: setlocale(LC_ALL, $localeString); from my bootstrapping (pasted below), $this->currency(1) returns '1,00 €' and all is fine.

The static function normalize in Zend/Locale/Math.php seems to make the wrong conversion.

My setup:

php-cgi --version PHP 5.3.3-7+squeeze3 with Suhosin-Patch (cgi-fcgi) (built: Jun 28 2011 08:20:54) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies with XCache v1.3.0, Copyright (c) 2005-2009, by mOo

with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

/usr/sbin/apache2 -v Server version: Apache/2.2.16 (Debian)

Server built: Mar 22 2011 21:14:10

Browser: Google Chrome 12.0.742.124

OS: Linux (Debian 6.0.2)

Env-Settings: export | grep -i lang declare -x GDM_LANG="de_DE.UTF-8" declare -x LANG="de_DE.UTF-8"

declare -x LANGUAGE=""

locale-settings (in the bootstrapping of my application): $localeString = 'de_DE'; setlocale(LC_ALL, $localeString); Zend_Registry::set('Zend_Locale', new Zend_Locale($localeString)); Zend_Registry::set('Zend_Currency', new Zend_Currency($localeString));


Hi, Michael Kühn! I've found the solution how to fix the issue. setlocale() must be called with LC_MESSAGES param

setlocale(LC_MESSAGES, $localeString);


the problem is a combination of Zend_Locale_Math::round() and Zend_Locale_Math::normalize(). Zend_Locale_Math::round() adds a ".0" to full integer values or rounds float values to the given precision. After this Zend_Locale_Math::normalize() gets called. With a locale setting that uses a "." as thousands sepecator, normalize() strips "."

I could fix the Problem by checking the value in normalize():

if (is_numeric($value)) {
    return (int) $value;