WordPress.org

Ready to get started?Download WordPress

Ideas

Multi-char thousands separator - French, Russian, Czech etc.

  1. honza.skypala
    Member

    Hi there,

    several languages (French, Russian, Czech and many others) use comma ',' as decimal separator and space ' ' as thousands separator in formatted numbers. While it may sound like easy cake, unfortunatelly it is not. The number can get word wrapped - due to space as thousand separator, which is bad. The number should stay together. Of course the solution would be to use non-breakable space (nbsp) as thousands separator. Well, there is a problem with PHP number_format function, that it does not accept multi-char thousands separators, but takes only first char from the string.

    I know this is problem caused by PHP, not by WordPress, but as long as the bug is there in PHP, the solution has to be provided on a higher level. For this reason I suggest to modify the functions.php file to handle this situation, with the following code:

    /**
     * Convert number to format based on the locale.
     *
     * @since 2.3.0
     *
     * @param mixed $number The number to convert based on locale.
     * @param int $decimals Precision of the number of decimal places.
     * @return string Converted number in string format.
     */
    function number_format_i18n( $number, $decimals = null ) {
    	global $wp_locale;
    	// let the user override the precision only
    	$decimals = ( is_null( $decimals ) ) ? $wp_locale->number_format['decimals'] : intval( $decimals );
    
    	return wp_number_format( $number, $decimals, $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep'] );
    }
    
    /**
     * Format number according to localization
     *
     * PHP native function number_format unfortunatelly does not support
     * decimal point or thousand separator longer than one character, e.g.
     * like ' '
     * This function does support multi-char decimal point and thousands
     * separator.
     * Source code copied from http://www.php.net/number_format, comment
     * by team at glossword dot biz. Thank you!
     *
     * @param mixed $number The number to convert based on locale.
     * @param int $decimals Precision of the number of decimal places.
     * @param string $dec_point Decimal point string
     * @param string $thousands_sep Thousands separator
     * @return string Converted number in string format.
     */
    function wp_number_format($n, $decimals = 0, $dec_point = '.', $thousands_sep = ',')
    {
        $b = explode('.', $n);
        $rn = '';
        $l = strlen($b[0]);
        /* Reverse string */
        for ($i = $l; $i > 3; $i -= 3)
        {
            $rn = $thousands_sep . substr($b[0], $i - 3, 3) . $rn;
        }
        /* sprintf() used to correct 0.79 to 0.790 */
        /* str_replace() used to correct decimals */
        /* str_repeat() used to correct decimals */
        return substr($b[0], 0, $i) . $rn . ($decimals
                ? $dec_point.(isset($b[1])
                    ? str_replace('0.', '', sprintf('%0.'.$decimals.'f', '0.'.$b[1]))
                    : str_repeat(0, $decimals))
                : '');
    }

    This code provides for full backwards WordPress compatibility, but allows translators to put the following into translations (well, they are allowed already, but now it does not produce the expected results):

    #: wp-includes/locale.php:187
    msgid 'number_format_thousands_sep|$thousands_sep argument for http://php.net/number_format, default is ,';
    msgstr ' ';

    Please, consider including this into WordPress, so I do not have to modify functions.php in every WordPress release.

    Posted: 5 years ago #
  2. honza.skypala
    Member

    (deleted, fixed in the post above)

    Posted: 5 years ago #
  3. honza.skypala
    Member

    (deleted, fixed in the post above)

    Posted: 5 years ago #
  4. honza.skypala
    Member

    Hi, I have already discovered a bug in the proposed wp_number_format function, did not round the number correctly, e.g. wp_number_format(4.967, 1). This fixes the bug:

    /**
     * Format number according to localization
     *
     * PHP native function number_format unfortunatelly does not support
     * decimal point or thousand separator longer than one character, e.g.
     * like  
     * This function does support multi-char decimal point and thousands
     * separator.
     * Source code copied from http://www.php.net/number_format, comment
     * by team at glossword dot biz. Thank you!
     *
     * @param mixed $number The number to convert based on locale.
     * @param int $decimals Precision of the number of decimal places.
     * @param string $dec_point Decimal point string
     * @param string $thousands_sep Thousands separator
     * @return string Converted number in string format.
     */
    function wp_number_format($n, $decimals = 0, $dec_point = '.', $thousands_sep = ',')
    {
        $b = explode('.', $n);
        $fract = sprintf('%0.'.$decimals.'f', '0.'.$b[1]);
        if ($fract[0] == '1') {
        	$b[0] = $b[0] + ($b[0] >= 0 ? 1 : -1);
        	$fract[0] = '0';
        }
        $rn = '';
        $l = strlen($b[0]);
        /* Reverse string */
        for ($i = $l; $i > 3; $i -= 3)
        {
            $rn = $thousands_sep . substr($b[0], $i - 3, 3) . $rn;
        }
        /* sprintf() used to correct 0.79 to 0.790 */
        /* str_replace() used to correct decimals */
        /* str_repeat() used to correct decimals */
        return substr($b[0], 0, $i) . $rn . ($decimals
                ? $dec_point.(isset($b[1])
                    ? str_replace('0.', '', $fract)
                    : str_repeat(0, $decimals))
                : '');
    }
    Posted: 5 years ago #
  5. A plugin can be used to fix this behaviour for the languages, which need it:

    http://core.trac.wordpress.org/ticket/10373

    Posted: 4 years ago #

RSS feed for this topic

Topic Closed

This topic has been closed to new replies.

  • Rating

    12345
    2 Votes
  • Status

    This is plugin territory

No tags yet.