Number formatting using letters, in PHP:
define('PR_NFORMAT_DEC_SEPARATOR', '.'); // decimals separator
define('PR_NFORMAT_THS_SEPARATOR', ','); // thousands separator
/**
*
* Formatting numbers using letters; ex: 1066345732 becomes 1.07B
* @param float $fValue
* @param int $nSupportedDecimals
* @return formatted string
*/
function customNumberFormatLetters($fValue, $nSupportedDecimals = 2) {
if(!preg_match('`^[0-9\.]+$`', $fValue)) {
return $fValue;
}
// get rid of decimals
$fValue = round($fValue);
// supported cases !!! order is IMPORTANT !!! the cases are teste in this order
$aCases = array(
array('no_chars' => 9, 'letter' => 'B'), // billions
array('no_chars' => 6, 'letter' => 'M'), // millions
);
$sNumberNice = $fValue;
// test suppoort cases
foreach($aCases as $aCase) {
if($fValue > (int)str_repeat('9', $aCase['no_chars'])) {
$fValue = $fValue / pow(10, $aCase['no_chars']);
if($nSupportedDecimals > 0) {
$fValue = $fValue * pow(10, $nSupportedDecimals);
$fValue = round($fValue);
$fValue = $fValue / (pow(10, $nSupportedDecimals));
} else {
$fValue = round($fValue);
}
$sNumberNice = number_format($fValue, $nSupportedDecimals, PR_NFORMAT_DEC_SEPARATOR, PR_NFORMAT_THS_SEPARATOR);
$sNumberNice = eraseEndingZeros($sNumberNice);
$sNumberNice .= $aCase['letter'];
break;
}
}
return $sNumberNice;
}
function eraseEndingZeros($fValueFormatted) {
// erase all ending zeros:
$aNparts = explode(PR_NFORMAT_DEC_SEPARATOR, $fValueFormatted);
if(count($aNparts) == 2) {
if(strlen($aNparts[1]) === 0 || preg_match('`^0+$`', $aNparts[1])) {
$fValueFormatted = $aNparts[0];
} elseif(strlen($aNparts[1]) === 1 && (string)$aNparts[1] !== '0') {
$fValueFormatted = $aNparts[0] . PR_NFORMAT_DEC_SEPARATOR . $aNparts[1];
} else {
$aNparts[1] = preg_replace('`^([0-9]+)([1-9])(0+)$`', '$1$2', $aNparts[1]);
$fValueFormatted = $aNparts[0] . PR_NFORMAT_DEC_SEPARATOR . $aNparts[1];
}
}
return $fValueFormatted;
}
define('PR_NFORMAT_DEC_SEPARATOR', '.'); // decimals separator
define('PR_NFORMAT_THS_SEPARATOR', ','); // thousands separator
/**
*
* Formatting numbers using letters; ex: 1066345732 becomes 1.07B
* @param float $fValue
* @param int $nSupportedDecimals
* @return formatted string
*/
function customNumberFormatLetters($fValue, $nSupportedDecimals = 2) {
if(!preg_match('`^[0-9\.]+$`', $fValue)) {
return $fValue;
}
// get rid of decimals
$fValue = round($fValue);
// supported cases !!! order is IMPORTANT !!! the cases are teste in this order
$aCases = array(
array('no_chars' => 9, 'letter' => 'B'), // billions
array('no_chars' => 6, 'letter' => 'M'), // millions
);
$sNumberNice = $fValue;
// test suppoort cases
foreach($aCases as $aCase) {
if($fValue > (int)str_repeat('9', $aCase['no_chars'])) {
$fValue = $fValue / pow(10, $aCase['no_chars']);
if($nSupportedDecimals > 0) {
$fValue = $fValue * pow(10, $nSupportedDecimals);
$fValue = round($fValue);
$fValue = $fValue / (pow(10, $nSupportedDecimals));
} else {
$fValue = round($fValue);
}
$sNumberNice = number_format($fValue, $nSupportedDecimals, PR_NFORMAT_DEC_SEPARATOR, PR_NFORMAT_THS_SEPARATOR);
$sNumberNice = eraseEndingZeros($sNumberNice);
$sNumberNice .= $aCase['letter'];
break;
}
}
return $sNumberNice;
}
function eraseEndingZeros($fValueFormatted) {
// erase all ending zeros:
$aNparts = explode(PR_NFORMAT_DEC_SEPARATOR, $fValueFormatted);
if(count($aNparts) == 2) {
if(strlen($aNparts[1]) === 0 || preg_match('`^0+$`', $aNparts[1])) {
$fValueFormatted = $aNparts[0];
} elseif(strlen($aNparts[1]) === 1 && (string)$aNparts[1] !== '0') {
$fValueFormatted = $aNparts[0] . PR_NFORMAT_DEC_SEPARATOR . $aNparts[1];
} else {
$aNparts[1] = preg_replace('`^([0-9]+)([1-9])(0+)$`', '$1$2', $aNparts[1]);
$fValueFormatted = $aNparts[0] . PR_NFORMAT_DEC_SEPARATOR . $aNparts[1];
}
}
return $fValueFormatted;
}
No comments:
Post a Comment