37

I have a question about formatting the Rupee currency (Indian Rupee - INR).

For example, numbers here are represented as:

1
10
100
1,000
10,000
1,00,000
10,00,000
1,00,00,000
10,00,00,000

Refer Indian Numbering System

I have to do with it PHP.

I have saw this question Displaying Currency in Indian Numbering Format. But couldn't able to get it for PHP my problem.

Update:

How to use money_format() in indian currency format?

Deepak Rai
  • 2,163
  • 3
  • 21
  • 36
Somnath Muluk
  • 55,015
  • 38
  • 216
  • 226

22 Answers22

63

You have so many options but money_format can do the trick for you.

Example:

$amount = '100000';
setlocale(LC_MONETARY, 'en_IN');
$amount = money_format('%!i', $amount);
echo $amount;

Output:

1,00,000.00

Note:

The function money_format() is only defined if the system has strfmon capabilities. For example, Windows does not, so money_format() is undefined in Windows.

Pure PHP Implementation - Works on any system:

$amount = '10000034000';
$amount = moneyFormatIndia( $amount );
echo $amount;

function moneyFormatIndia($num) {
    $explrestunits = "" ;
    if(strlen($num)>3) {
        $lastthree = substr($num, strlen($num)-3, strlen($num));
        $restunits = substr($num, 0, strlen($num)-3); // extracts the last three digits
        $restunits = (strlen($restunits)%2 == 1)?"0".$restunits:$restunits; // explodes the remaining digits in 2's formats, adds a zero in the beginning to maintain the 2's grouping.
        $expunit = str_split($restunits, 2);
        for($i=0; $i<sizeof($expunit); $i++) {
            // creates each of the 2's group and adds a comma to the end
            if($i==0) {
                $explrestunits .= (int)$expunit[$i].","; // if is first value , convert into integer
            } else {
                $explrestunits .= $expunit[$i].",";
            }
        }
        $thecash = $explrestunits.$lastthree;
    } else {
        $thecash = $num;
    }
    return $thecash; // writes the final format where $currency is the currency symbol.
}
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Baba
  • 94,024
  • 28
  • 166
  • 217
  • If using windows then use [this function for money_format()](http://stackoverflow.com/questions/9974704/cross-platform-money-format-linux-and-windows/10042668#10042668). – Somnath Muluk Apr 06 '12 at 11:19
  • 2
    @Somnath Muluk that does not give accurate formatting when using locale with `en_IN` – Baba Apr 06 '12 at 11:23
  • Is there any settings to remove zeros after zero if given number is whole number(other than round() function)? – Somnath Muluk Apr 06 '12 at 11:25
  • `substr_replace($string ,"",-1);` that's the cheat i know ... @Somnath Muluk – Baba Apr 06 '12 at 11:43
  • By doing settings to function money_format() isn't that possible? I don't want to use any hacky method. – Somnath Muluk Apr 06 '12 at 12:37
  • What about a PURE PHP implementation using number_format ... see http://php.net/manual/fr/function.number-format.php – Baba Apr 06 '12 at 12:42
  • But with moneyFormatIndia(), if number is '10000034000.45' then it gives '1,00,00,03,40,00,.45' with number format instead of giving '10,00,00,34,000.45'. If number is whole then I don't want numbers after decimal otherwise I want it. – Somnath Muluk Apr 07 '12 at 07:00
  • I have accepted answer, because it helped me to get towards solution. – Somnath Muluk Apr 07 '12 at 09:10
  • 6
    Poor function not working with decimals and negative. – RN Kushwaha Nov 13 '14 at 06:09
  • 1
    Thanks. After spending over 40 mins trying to figure out why money_format did not work on my Ubuntu 14.04 instance running over nginx on Amazon’s AWS EC2, I settled with this for now. The usual money_format works great on my local homestead machine but couldn’t get the production copy to work. Here’s a [gist](https://gist.github.com/SaifurRahmanMohsin/6f8f37b79ba85db57375) using **money_format** and @Baba's code as a fallback for anyone who faces the same issue. – Saifur Rahman Mohsin Oct 08 '15 at 20:42
  • this returns wrong output for 5 digit negative value. Ex. for -10000 it returns 0,10,000 – Abasaheb Gaware Jul 09 '18 at 09:08
  • @Baba This is excellent. But one small correction. just before `$thecash = $explrestunits.$lastthree;` we need to add one more line as `$explrestunits = rtrim($explrestunits, ',');` otherwise number shows as `88,43,46,.73` – Anto S Feb 26 '19 at 08:57
  • Even if on Linux, you might need to generate the `en_IN` locale using the following commands in succession: `sudo locale-gen en_IN.UTF-8` and then `sudo update-locale` – Madhur Bhaiya Jun 25 '19 at 06:30
  • Second code giving issue for decimal numbers: https://3v4l.org/vYuPC – Alive to die - Anant Feb 09 '21 at 05:11
  • Thank you that works better, but if your number has decimal place and more than 3 after decimal it will give a wrong output, only we have to do is cut the left side of decimal then process and while return decimal result add right side of decimal to it. wonderful thank you very much for the function @Baba – Gopipuli Nov 13 '21 at 06:48
  • If you want to display the rupee symbol, you may refer - https://www.sitepoint.com/community/t/how-to-insert-indian-rupees-symbol-in-php/248733/3 – Ravindra Gullapalli May 23 '23 at 04:59
26
$num = 1234567890.123;

$num = preg_replace("/(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/i", "$1,", $num);

echo $num;

// Input : 1234567890.123

// Output : 1,23,45,67,890.123


// Input : -1234567890.123

// Output : -1,23,45,67,890.123
Zoe
  • 27,060
  • 21
  • 118
  • 148
Suresh Pandi
  • 361
  • 3
  • 6
  • I think this should be the fallback method if LC_MONETARY fails. – Farveaz Mar 28 '19 at 12:15
  • I am using Windows and linux hosting, this method works on both like charm, this is the best and shortest method possible for converting any number to INR format. – SuKu Jun 27 '19 at 03:20
  • This is the best answer, but one problem is that if you have 0 after a decimal value it removes the 0. For example, if the input is. `10000000.40` the output will be `1,00,00,000.4`. If we can make the zero to be there that would be great. – user7747472 Feb 02 '23 at 07:15
13
echo 'Rs. '.IND_money_format(1234567890);

function IND_money_format($money){
    $len = strlen($money);
    $m = '';
    $money = strrev($money);
    for($i=0;$i<$len;$i++){
        if(( $i==3 || ($i>3 && ($i-1)%2==0) )&& $i!=$len){
            $m .=',';
        }
        $m .=$money[$i];
    }
    return strrev($m);
}

NOTE:: it is not tested on float values and it suitable for only Integer

Pathik Vejani
  • 4,263
  • 8
  • 57
  • 98
Vishal Chanana
  • 114
  • 2
  • 6
  • As **money_format()** doesn't work on Windows. this works for me. – Anon30 May 20 '16 at 07:44
  • 1
    this returns wrong output for 5 digit negative value. Ex. for -10000 it returns -,10,000. solution for this is=> Add if condition like -> if($money[$i]!="-"){ $m .=','; } – Abasaheb Gaware Jul 09 '18 at 09:14
11

The example you've linked is making use of the ICU libraries which are available with PHP in the intl Extension­Docs:

$fmt = new NumberFormatter($locale = 'en_IN', NumberFormatter::CURRENCY);
echo $fmt->format(10000000000.1234)."\n"; # Rs 10,00,00,00,000.12

Or maybe better fitting in your case:

$fmt = new NumberFormatter($locale = 'en_IN', NumberFormatter::DECIMAL);
echo $fmt->format(10000000000)."\n"; # 10,00,00,00,000
Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
  • That works on windows, the example given has been actually run on windows, see [PHP intl extension](http://stackoverflow.com/q/1451468/367456). – hakre Apr 06 '12 at 11:20
  • How to use `intl Extension­Docs:` library for codeigniter framework? I am unable to use this functions. – Somnath Muluk Apr 07 '12 at 07:08
  • @SomnathMuluk: It's just PHP, you use it as-is. If it looks too complicated for you, wrap it into a function of it's own for starters. – hakre Apr 07 '12 at 08:25
6

Simply use below function to format in INR.

function amount_inr_format($amount) {
    $fmt = new \NumberFormatter($locale = 'en_IN', NumberFormatter::DECIMAL);
    return $fmt->format($amount);
}
Bishwanath Jha
  • 399
  • 3
  • 10
5

Check this code, it works 100% for Indian Rupees format with decimal format. You can use numbers like :

123456.789 123.456 123.4 123 and 1,2,3,4,5,6,7,8,9,.222

function moneyFormatIndia($num){

$explrestunits = "" ;
$num = preg_replace('/,+/', '', $num);
$words = explode(".", $num);
$des = "00";
if(count($words)<=2){
    $num=$words[0];
    if(count($words)>=2){$des=$words[1];}
    if(strlen($des)<2){$des="$des";}else{$des=substr($des,0,2);}
}
if(strlen($num)>3){
    $lastthree = substr($num, strlen($num)-3, strlen($num));
    $restunits = substr($num, 0, strlen($num)-3); // extracts the last three digits
    $restunits = (strlen($restunits)%2 == 1)?"0".$restunits:$restunits; // explodes the remaining digits in 2's formats, adds a zero in the beginning to maintain the 2's grouping.
    $expunit = str_split($restunits, 2);
    for($i=0; $i<sizeof($expunit); $i++){
        // creates each of the 2's group and adds a comma to the end
        if($i==0)
        {
            $explrestunits .= (int)$expunit[$i].","; // if is first value , convert into integer
        }else{
            $explrestunits .= $expunit[$i].",";
        }
    }
    $thecash = $explrestunits.$lastthree;
} else {
    $thecash = $num;
}
return "$thecash.$des"; // writes the final format where $currency is the currency symbol.

}
Dray
  • 887
  • 8
  • 25
user3314233
  • 43
  • 1
  • 1
3

When money_format is not available :

function format($amount): string
{
    list ($number, $decimal) = explode('.', sprintf('%.2f', floatval($amount)));

    $sign = $number < 0 ? '-' : '';

    $number = abs($number);

    for ($i = 3; $i < strlen($number); $i += 3)
    {
        $number = substr_replace($number, ',', -$i, 0);
    }

    return $sign . $number . '.' . $decimal;

}
Sonam Gurung
  • 117
  • 1
  • 3
2
<?php
$amount = '-100000.22222';    // output -1,00,000.22 
//$amount = '0100000.22222';  // output 1,00,000.22 
//$amount = '100000.22222';   // output 1,00,000.22 
//$amount = '100000.';       // output 1,00,000.00 
//$amount = '100000.2';     // output 1,00,000.20
//$amount = '100000.0';    // output 1,00,000.00 
//$amount = '100000';      // output 1,00,000.00 

echo $aaa = moneyFormatIndia($amount);

function moneyFormatIndia($amount)
    {

        $amount = round($amount,2);

        $amountArray =  explode('.', $amount);
        if(count($amountArray)==1)
        {
            $int = $amountArray[0];
            $des=00;
        }
        else {
            $int = $amountArray[0];
            $des=$amountArray[1];
        }
        if(strlen($des)==1)
        {
            $des=$des."0";
        }
        if($int>=0)
        {
            $int = numFormatIndia( $int );
            $themoney = $int.".".$des;
        }

        else
        {
            $int=abs($int);
            $int = numFormatIndia( $int );
            $themoney= "-".$int.".".$des;
        }   
        return $themoney;
    }

function numFormatIndia($num)
    {

        $explrestunits = "";
        if(strlen($num)>3)
        {
            $lastthree = substr($num, strlen($num)-3, strlen($num));
            $restunits = substr($num, 0, strlen($num)-3); // extracts the last three digits
            $restunits = (strlen($restunits)%2 == 1)?"0".$restunits:$restunits; // explodes the remaining digits in 2's formats, adds a zero in the beginning to maintain the 2's grouping.
            $expunit = str_split($restunits, 2);
            for($i=0; $i<sizeof($expunit); $i++) {
                // creates each of the 2's group and adds a comma to the end
                if($i==0) {
                    $explrestunits .= (int)$expunit[$i].","; // if is first value , convert into integer
                } else {
                    $explrestunits .= $expunit[$i].",";
                }
            }
            $thecash = $explrestunits.$lastthree;
        } else {
            $thecash = $num;
        }
        return $thecash; // writes the final format where $currency is the currency symbol.
    }
?>
Sachin Saini
  • 137
  • 2
  • 3
  • 10
2

I think this a quick and simplest solution:-

        function formatToInr($number){
        $number=round($number,2);
        // windows is not supported money_format
    if(setlocale(LC_MONETARY, 'en_IN')){
         return money_format('%!'.$decimal.'n', $number);
         }
     else {
        if(floor($number) == $number) {
            $append='.00';
        }else{
            $append='';
        }
        $number = preg_replace("/(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/i", "$1,", $number);
        return $number.$append;
        }
    }
1

So if I'm reading that right, the Indian Numbering System separates the thousands, then every power of a hundred past that? Hmm...

Perhaps something like this?

function indian_number_format($num) {
    $num = "".$num;
    if( strlen($num) < 4) return $num;
    $tail = substr($num,-3);
    $head = substr($num,0,-3);
    $head = preg_replace("/\B(?=(?:\d{2})+(?!\d))/",",",$head);
    return $head.",".$tail;
}
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
1

I have used different format parameters to money_format() for my output.

setlocale(LC_MONETARY, 'en_IN');
if (ctype_digit($amount) ) {
     // is whole number
     // if not required any numbers after decimal use this format 
     $amount = money_format('%!.0n', $amount);
}
else {
     // is not whole number
     $amount = money_format('%!i', $amount);
}
//$amount=10043445.7887 outputs 1,00,43,445.79
//$amount=10043445 outputs 1,00,43,445
Somnath Muluk
  • 55,015
  • 38
  • 216
  • 226
1
$amount=-3000000000111.11;
$amount<0?(($sign='-').($amount*=-1)):$sign=''; //Extracting sign from given amount
$pos=strpos($amount, '.'); //Identifying the decimal point position
$amt=  substr($amount, $pos-3); // Extracting last 3 digits of integer part along with fractional part
$amount=  substr($amount,0, $pos-3); //removing the extracted part from amount
for(;strlen($amount);$amount=substr($amount,0,-2)) // Now loop through each 2 digits of remaining integer part
    $amt=substr ($amount,-2).','.$amt; //forming Indian Currency format by appending (,) for each 2 digits
echo $sign.$amt; //Appending sign
Kishore
  • 11
  • 3
0

You should check the number_format function.Here is the link

Separating thousands with commas will look like

$rupias = number_format($number, 2, ',', ',');
Elena
  • 157
  • 1
  • 7
0

Above Function Not working with Decimal

$amount = 10000034000.001;
$amount = moneyFormatIndia( $amount );
echo $amount;




function moneyFormatIndia($num){
        $nums = explode(".",$num);
        if(count($nums)>2){
            return "0";
        }else{
        if(count($nums)==1){
            $nums[1]="00";
        }
        $num = $nums[0];
        $explrestunits = "" ;
        if(strlen($num)>3){
            $lastthree = substr($num, strlen($num)-3, strlen($num));
            $restunits = substr($num, 0, strlen($num)-3); 
            $restunits = (strlen($restunits)%2 == 1)?"0".$restunits:$restunits; 
            $expunit = str_split($restunits, 2);
            for($i=0; $i<sizeof($expunit); $i++){

                if($i==0)
                {
                    $explrestunits .= (int)$expunit[$i].","; 
                }else{
                    $explrestunits .= $expunit[$i].",";
                }
            }
            $thecash = $explrestunits.$lastthree;
        } else {
            $thecash = $num;
        }
        return $thecash.".".$nums[1]; 
        }
    }

Answer : 10,00,00,34,000.001

Dhaval Dhami
  • 75
  • 1
  • 8
0

It's my very own function to do the task

function bd_money($num) {
    $pre = NULL; $sep = array(); $app = '00';
    $s=substr($num,0,1);
    if ($s=='-') {$pre= '-';$num = substr($num,1);}
    $num=explode('.',$num);
    if (count($num)>1) $app=$num[1];
    if (strlen($num[0])<4) return $pre . $num[0] . '.' . $app;
    $th=substr($num[0],-3);
    $hu=substr($num[0],0,-3);
    while(strlen($hu)>0){$sep[]=substr($hu,-2); $hu=substr($hu,0,-2);}
    return $pre.implode(',',array_reverse($sep)).','.$th.'.'.$app;
}

It took 0.0110 Seconds per THOUSAND query while number_format took 0.001 only. Always try to use PHP native functions only when performance is target issue.

Abbas
  • 552
  • 5
  • 8
0

Use this function:

function addCommaToRs($amt, &$ret, $dec='', $sign=''){
    if(preg_match("/-/",$amt)){
        $amts=explode('-',$amt);
        $amt=$amts['1'];
        static $sign='-';
    } 
    if(preg_match("/\./",$amt)){
        $amts=explode('.',$amt);
        $amt=$amts['0'];
        $l=strlen($amt);
        static $dec;
        $dec=$amts['1'];
    } else {
        $l=strlen($amt);
    }
    if($l>3){
        if($l%2==0){
            $ret.= substr($amt,0,1);
            $ret.= ",";
            addCommaToRs(substr($amt,1,$l),$ret,$dec);
        } else{
            $ret.=substr($amt,0,2);
            $ret.= ",";     
            addCommaToRs(substr($amt,2,$l),$ret,$dec);
        }
    } else {
        $ret.= $amt;
        if($dec) $ret.=".".$dec;
    }
    return $sign.$ret; 
}

Call it like this:

$amt = '';
echo addCommaToRs(123456789.123,&$amt,0);

This will return 12,34,567.123.

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
RN Kushwaha
  • 2,081
  • 3
  • 29
  • 40
0
$r=explode('.',12345601.20);

$n = $r[0];
$len = strlen($n); //lenght of the no
$num = substr($n,$len-3,3); //get the last 3 digits
$n = $n/1000; //omit the last 3 digits already stored in $num
while($n > 0) //loop the process - further get digits 2 by 2
{
    $len = strlen($n);
    $num = substr($n,$len-2,2).",".$num;
    $n = round($n/100);
}
echo "Rs.".$num.'.'.$r[1];
Code Lღver
  • 15,573
  • 16
  • 56
  • 75
0

If you dont want to use any inbuilt function in my case i was doing on iis server so was unable to use one the function in php so did this

$num = -21324322.23;


moneyFormatIndiaPHP($num);
function moneyFormatIndiaPHP($num){
    //converting it to string 
    $numToString = (string)$num;

    //take care of decimal values
    $change = explode('.', $numToString);

    //taking care of minus sign
    $checkifminus =  explode('-', $change[0]);


    //if minus then change the value as per
    $change[0] = (count($checkifminus) > 1)? $checkifminus[1] : $checkifminus[0];

    //store the minus sign for further
    $min_sgn = '';
    $min_sgn = (count($checkifminus) > 1)?'-':'';



    //catch the last three
    $lastThree = substr($change[0], strlen($change[0])-3);



    //catch the other three
    $ExlastThree = substr($change[0], 0 ,strlen($change[0])-3);


    //check whethr empty 
    if($ExlastThree != '')
        $lastThree = ',' . $lastThree;


    //replace through regex
    $res = preg_replace("/\B(?=(\d{2})+(?!\d))/",",",$ExlastThree);

    //main container num
    $lst = '';

    if(isset($change[1]) == ''){
        $lst =  $min_sgn.$res.$lastThree;
    }else{
        $lst =  $min_sgn.$res.$lastThree.".".$change[1];
    }

    //special case if equals to 2 then 
    if(strlen($change[0]) === 2){
        $lst = str_replace(",","",$lst);
    }

    return $lst;
}
0

This for both integer and float values

    function indian_money_format($number)
    {

        if(strstr($number,"-"))
        {
            $number = str_replace("-","",$number);
            $negative = "-";
        }

        $split_number = @explode(".",$number);

        $rupee = $split_number[0];
        $paise = @$split_number[1];

        if(@strlen($rupee)>3)
        {
            $hundreds = substr($rupee,strlen($rupee)-3);
            $thousands_in_reverse = strrev(substr($rupee,0,strlen($rupee)-3));
            $thousands = '';
            for($i=0; $i<(strlen($thousands_in_reverse)); $i=$i+2)
            {
                $thousands .= $thousands_in_reverse[$i].$thousands_in_reverse[$i+1].",";
            }
            $thousands = strrev(trim($thousands,","));
            $formatted_rupee = $thousands.",".$hundreds;

        }
        else
        {
            $formatted_rupee = $rupee;
        }

        if((int)$paise>0)
        {
            $formatted_paise = ".".substr($paise,0,2);
        }else{
            $formatted_paise = '.00';
        }

        return $negative.$formatted_rupee.$formatted_paise;

    }
Shailesh Chauhan
  • 673
  • 5
  • 20
0
<?php
    function moneyFormatIndia($num) 
    {
        //$num=123456789.00;
        $result='';
        $sum=explode('.',$num);
        $after_dec=$sum[1];
        $before_dec=$sum[0];
        $result='.'.$after_dec;
        $num=$before_dec;
        $len=strlen($num);
        if($len<=3) 
        {
            $result=$num.$result;
        }
        else
        {
            if($len<=5)
            {
                $result='Rs '.substr($num, 0,$len-3).','.substr($num,$len-3).$result;
                return $result;
            }
            else
            {
                $ls=strlen($num);
                $result=substr($num, $ls-5,2).','.substr($num, $ls-3).$result;
                $num=substr($num, 0,$ls-5);
                while(strlen($num)!=0)
                {
                    $result=','.$result;
                    $ls=strlen($num);
                    if($ls<=2)
                    {
                        $result='Rs. '.$num.$result;
                        return $result;
                    }
                    else
                    {
                        $result=substr($num, $ls-2).$result;
                        $num=substr($num, 0,$ls-2);
                    }
                }
            }
        }
    }
?>
Vijay Gawade
  • 51
  • 1
  • 4
-3

heres is simple thing u can do ,

 float amount = 100000;

 NumberFormat formatter = NumberFormat.getCurrencyInstance(new Locale("en", "IN"));

 String moneyString = formatter.format(amount);

 System.out.println(moneyString);

The output will be , Rs.100,000.00 .

CleanX
  • 1,158
  • 3
  • 17
  • 25
-3
declare @Price decimal(26,7)
Set @Price=1234456677
select FORMAT(@Price,  'c', 'en-In')

Result:

1,23,44,56,677.00
arogachev
  • 33,150
  • 7
  • 114
  • 117
Ramya
  • 1