Yii CNumberFormatter FormatPercentage Sucks

I was working on some code that I wanted to use a number formatter on. In this specific project I use the Yii framework which provides a class called CNumberFormatter to handle such things. I was looking specifically for the formatPercentage method after digging around for a little bit.

I noticed that the method only takes in a raw number. Which seems very odd why wouldn’t you be able to pass in a precision. Not all percentages should be rounded with the same precision. So for example it would take in ‘0.245’. I would expect an easy way to override the currently rounding rules. But from the documentation I read that is not possible. The rounding rules for this specific case is barred deep inside the framework in a translation file. This would work great if everybody wanted to round their decimals up to the nearest decimal. So for example the number above would round to 3% not 2.45% as I wanted. After digging around for 15 or so minutes I gave up and just rolled my own formatter. It’s a pretty big disappointment that the framework is unable to handle such a simple request. In comparison I use Ruby on Rails for my daily job and they have a method that actually takes in a precision argument number_to_percentage. This forward thinking really makes me regret not starting this project out in Ruby on Rails. Of course when you have been coding on it for over five years it’s nearly impossible to get out. So I created my own extension and am going to roll with that for now. But it’s pretty disappointing when the framework isn’t able to help in these simple situations.

Here is my simple solution to the problem. All is well now.


<?php
class Percentage extends CNumberFormatter {
    public function __construct() {
        // pass in en_US by default this could be expanded in the future for more currency
        parent::__construct('en_US');
    }

    public function init() {
    }

    public function format($number, $roundTo=2) {
        return number_format(round(($number * 100),$roundTo), $roundTo).'%';
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *