php人民幣小寫轉大寫函式,不限長度,精確到分

餘二五發表於2017-11-21

在列印發票或顯示賬單的時候我們經常會需要將人民幣的金額由小寫轉為大寫,下面是我改進的一個函式,支援如下的特性:

  1. 1.支援天文數字,整數位理論上可以無限的長;
  2. 2.支援小數,對於貨幣,一般精確到小數後兩位,可以設定小數位是否四捨五入;
  3. 3.支援自定義貨幣單位,有的系統要求大寫是”圓”,有的要求是”元”,可以自定義;
  4. 4.支援整數以0結束並含有小數的數字自定義末尾補”零”,比如有的系統要求1960.30這樣的數字轉大寫之後是”壹仟玖佰陸拾元叄角”,而有的系統則要求”壹仟玖佰陸拾元零叄角”,這兩種情況按”正確填寫票據和結算憑證的基本規定“都是正確的,現在可已自定義.

 


  1. /** 
  2.  * 人民幣小寫轉大寫 
  3.  * 
  4.  * @param string $number 數值 
  5.  * @param string $int_unit 幣種單位,預設”元”,有的需求可能為”圓” 
  6.  * @param bool $is_round 是否對小數進行四捨五入 
  7.  * @param bool $is_extra_zero 是否對整數部分以0結尾,小數存在的數字附加0,比如1960.30, 
  8.  *             有的系統要求輸出”壹仟玖佰陸拾元零叄角”,實際上”壹仟玖佰陸拾元叄角”也是對的 
  9.  * @return string 
  10.  */ 
  11. function num2rmb($number = 0, $int_unit = `元`$is_round = TRUE, $is_extra_zero = FALSE) 
  12.     // 將數字切分成兩段 
  13.     $parts = explode(`.`$number, 2); 
  14.     $int = isset($parts[0]) ? strval($parts[0]) : `0`
  15.     $dec = isset($parts[1]) ? strval($parts[1]) : 
  16.  
  17.     // 如果小數點後多於2位,不四捨五入就直接截,否則就處理 
  18.     $dec_len = strlen($dec); 
  19.     if (isset($parts[1]) && $dec_len > 2) 
  20.     { 
  21.         $dec = $is_round 
  22.                 ? substr(strrchr(strval(round(floatval(“0.”.$dec), 2)), `.`), 1) 
  23.                 : substr($parts[1], 0, 2); 
  24.     } 
  25.  
  26.     // 當number為0.001時,小數點後的金額為0元 
  27.     if(empty($int) && empty($dec)) 
  28.     { 
  29.         return `零`
  30.     } 
  31.  
  32.     // 定義 
  33.     $chs = array(`0`,`壹`,`貳`,`叄`,`肆`,`伍`,`陸`,`柒`,`捌`,`玖`); 
  34.     $uni = array(,`拾`,`佰`,`仟`); 
  35.     $dec_uni = array(`角``分`); 
  36.     $exp = array(`萬`); 
  37.     $res = 
  38.  
  39.     // 整數部分從右向左找 
  40.     for($i = strlen($int) – 1, $k = 0; $i >= 0; $k++) 
  41.     { 
  42.         $str = 
  43.         // 按照中文讀寫習慣,每4個字為一段進行轉化,i一直在減 
  44.         for($j = 0; $j < 4 && $i >= 0; $j++, $i–) 
  45.         { 
  46.             $u = $int{$i} > 0 ? $uni[$j] : // 非0的數字後面新增單位 
  47.             $str = $chs[$int{$i}] . $u . $str
  48.         } 
  49.         //echo $str.”|”.($k – 2).”<br>”; 
  50.         $str = rtrim($str`0`);// 去掉末尾的0 
  51.         $str = preg_replace(“/0+/”“零”$str); // 替換多個連續的0 
  52.         if(!isset($exp[$k])) 
  53.         { 
  54.             $exp[$k] = $exp[$k – 2] . `億`// 構建單位 
  55.         } 
  56.         $u2 = $str !=  ? $exp[$k] : 
  57.         $res = $str . $u2 . $res
  58.     } 
  59.  
  60.     // 如果小數部分處理完之後是00,需要處理下 
  61.     $dec = rtrim($dec`0`); 
  62.  
  63.     // 小數部分從左向右找 
  64.     if(!empty($dec)) 
  65.     { 
  66.         $res .= $int_unit
  67.  
  68.         // 是否要在整數部分以0結尾的數字後附加0,有的系統有這要求 
  69.         if ($is_extra_zero
  70.         { 
  71.             if (substr($int, -1) === `0`
  72.             { 
  73.                 $res.= `零`
  74.             } 
  75.         } 
  76.  
  77.         for($i = 0, $cnt = strlen($dec); $i < $cnt$i++) 
  78.         { 
  79.             $u = $dec{$i} > 0 ? $dec_uni[$i] : // 非0的數字後面新增單位 
  80.             $res .= $chs[$dec{$i}] . $u
  81.         } 
  82.         $res = rtrim($res`0`);// 去掉末尾的0 
  83.         $res = preg_replace(“/0+/”“零”$res); // 替換多個連續的0 
  84.     } 
  85.     else 
  86.     { 
  87.         $res .= $int_unit . `整`
  88.     } 
  89.     return $res
  90.  
  91. echo “<pre>”
  92. $number = “1000000000000000012345678900.501”
  93. echo $number.“:”.num2rmb($number); 
  94. echo 
  95. $number = “1960.30”
  96. echo $number.“:”.num2rmb($number); 
  97. echo 
  98. $number = “1960.30”
  99. echo $number.“:”.num2rmb($number“圓”, true, true); 
  100. echo 
  101. $number = “123456789.005”
  102. echo $number.“:”.num2rmb($number); 
  103. echo 
  104. $number = “123456789.005”
  105. echo $number.“:”.num2rmb($number“元”, false); 
  106. echo 
  107. $number = “10000000000000000060009.101”
  108. echo $number.“:”.num2rmb($number); 
  109. echo 
  110. $number = “1680.32”
  111. echo $number.“:”.num2rmb($number); 

 輸出結果:


  1. 1000000000000000012345678900.501:壹仟億億億零壹佰貳拾叄億肆仟伍佰陸拾柒萬捌仟玖佰元伍角 
  2. 1960.30:壹仟玖佰陸拾元叄角 
  3. 1960.30:壹仟玖佰陸拾圓零叄角 
  4. 123456789.005:壹億貳仟叄佰肆拾伍萬陸仟柒佰捌拾玖元零壹分 
  5. 123456789.005:壹億貳仟叄佰肆拾伍萬陸仟柒佰捌拾玖元整 
  6. 10000000000000000060009.101:壹佰萬億億零陸萬零玖元壹角 
  7. 1680.32:壹仟陸佰捌拾元叄角貳分 
本文轉自 ustb80 51CTO部落格,原文連結:http://blog.51cto.com/ustb80/1035327,如需轉載請自行聯絡原作者


相關文章