In PHP, is there an easy way to convert a number to a word? For instance, 27 to twenty-seven.
In PHP, is there an easy way to convert a number to a word? For instance, 27 to twenty-seven.
I found some (2007/2008) source-code online and as it is copyright but I can use it freely and modify it however I want, so I place it here and re-license under CC-Wiki:
<?php
/**
* English Number Converter - Collection of PHP functions to convert a number
* into English text.
*
* This exact code is licensed under CC-Wiki on Stackoverflow.
* http://creativecommons.org/licenses/by-sa/3.0/
*
* @link http://stackoverflow.com/q/277569/367456
* @question Is there an easy way to convert a number to a word in PHP?
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2007-2008 Brenton Fletcher. http://bloople.net/num2text
* You can use this freely and modify it however you want.
*/
function convertNumber($number)
{
list($integer, $fraction) = explode(".", (string) $number);
$output = "";
if ($integer{0} == "-")
{
$output = "negative ";
$integer = ltrim($integer, "-");
}
else if ($integer{0} == "+")
{
$output = "positive ";
$integer = ltrim($integer, "+");
}
if ($integer{0} == "0")
{
$output .= "zero";
}
else
{
$integer = str_pad($integer, 36, "0", STR_PAD_LEFT);
$group = rtrim(chunk_split($integer, 3, " "), " ");
$groups = explode(" ", $group);
$groups2 = array();
foreach ($groups as $g)
{
$groups2[] = convertThreeDigit($g{0}, $g{1}, $g{2});
}
for ($z = 0; $z < count($groups2); $z++)
{
if ($groups2[$z] != "")
{
$output .= $groups2[$z] . convertGroup(11 - $z) . (
$z < 11
&& !array_search('', array_slice($groups2, $z + 1, -1))
&& $groups2[11] != ''
&& $groups[11]{0} == '0'
? " and "
: ", "
);
}
}
$output = rtrim($output, ", ");
}
if ($fraction > 0)
{
$output .= " point";
for ($i = 0; $i < strlen($fraction); $i++)
{
$output .= " " . convertDigit($fraction{$i});
}
}
return $output;
}
function convertGroup($index)
{
switch ($index)
{
case 11:
return " decillion";
case 10:
return " nonillion";
case 9:
return " octillion";
case 8:
return " septillion";
case 7:
return " sextillion";
case 6:
return " quintrillion";
case 5:
return " quadrillion";
case 4:
return " trillion";
case 3:
return " billion";
case 2:
return " million";
case 1:
return " thousand";
case 0:
return "";
}
}
function convertThreeDigit($digit1, $digit2, $digit3)
{
$buffer = "";
if ($digit1 == "0" && $digit2 == "0" && $digit3 == "0")
{
return "";
}
if ($digit1 != "0")
{
$buffer .= convertDigit($digit1) . " hundred";
if ($digit2 != "0" || $digit3 != "0")
{
$buffer .= " and ";
}
}
if ($digit2 != "0")
{
$buffer .= convertTwoDigit($digit2, $digit3);
}
else if ($digit3 != "0")
{
$buffer .= convertDigit($digit3);
}
return $buffer;
}
function convertTwoDigit($digit1, $digit2)
{
if ($digit2 == "0")
{
switch ($digit1)
{
case "1":
return "ten";
case "2":
return "twenty";
case "3":
return "thirty";
case "4":
return "forty";
case "5":
return "fifty";
case "6":
return "sixty";
case "7":
return "seventy";
case "8":
return "eighty";
case "9":
return "ninety";
}
} else if ($digit1 == "1")
{
switch ($digit2)
{
case "1":
return "eleven";
case "2":
return "twelve";
case "3":
return "thirteen";
case "4":
return "fourteen";
case "5":
return "fifteen";
case "6":
return "sixteen";
case "7":
return "seventeen";
case "8":
return "eighteen";
case "9":
return "nineteen";
}
} else
{
$temp = convertDigit($digit2);
switch ($digit1)
{
case "2":
return "twenty-$temp";
case "3":
return "thirty-$temp";
case "4":
return "forty-$temp";
case "5":
return "fifty-$temp";
case "6":
return "sixty-$temp";
case "7":
return "seventy-$temp";
case "8":
return "eighty-$temp";
case "9":
return "ninety-$temp";
}
}
}
function convertDigit($digit)
{
switch ($digit)
{
case "0":
return "zero";
case "1":
return "one";
case "2":
return "two";
case "3":
return "three";
case "4":
return "four";
case "5":
return "five";
case "6":
return "six";
case "7":
return "seven";
case "8":
return "eight";
case "9":
return "nine";
}
}
Alternatively, you can use the NumberFormatter class from intl package in PHP . Here's a sample code to get you started (for commandline):
<?php
if ($argc < 3)
{
echo "usage: php {$argv[0]} lang-tag number ...\n";
exit;
}
array_shift($argv);
$lang_tag = array_shift($argv);
$nf1 = new NumberFormatter($lang_tag, NumberFormatter::DECIMAL);
$nf2 = new NumberFormatter($lang_tag, NumberFormatter::SPELLOUT);
foreach ($argv as $num)
{
echo $nf1->format($num).' is '.$nf2->format($num)."\n";
}
There is the Numbers_Words package in PECL. It does exactly what you ask for. The following languages are supported:
You can use the NumberFormatter Class:
$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format($myNumber);
Yes there is. without using a library you just need to follow this..
First you need to check in your server if ;extension=php_intl.dll is enabled in your php.ini if still not work you need to see this answer.
intl extension php_intl.dll with wamp
after successfully moving all the files starts with icu.
from: <wamp_installation_path>/bin/php/php5.4.3/
to: <wamp_installation_path>/bin/apache/apache2.2.22/bin/
and restart your server.
try to run this code:
$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format(123456);
it will show the output of one hundred twenty-three thousand four hundred fifty-six.
hope that helps everyone :).
<?php
$grandTotalAmount = 700000000;
echo ($grandTotalAmount == round($grandTotalAmount)) ? convert_number_to_words(floatval($grandTotalAmount)) . ' Only' : convert_number_to_words(floatval($grandTotalAmount)) . ' Only';
function convert_number_to_words($number) {
$hyphen = ' ';
$conjunction = ' and ';
$separator = ', ';
$negative = 'negative ';
$decimal = ' Thai Baht And ';
$dictionary = array(
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
10 => 'ten',
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
20 => 'twenty',
30 => 'thirty',
40 => 'fourty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety',
100 => 'hundred',
1000 => 'thousand',
1000000 => 'million',
1000000000 => 'billion',
1000000000000 => 'trillion',
1000000000000000 => 'quadrillion',
1000000000000000000 => 'quintillion'
);
if (!is_numeric($number)) {
return false;
}
if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) {
// overflow
trigger_error(
'convert_number_to_words only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX, E_USER_WARNING
);
return false;
}
if ($number < 0) {
return $negative . convert_number_to_words(abs($number));
}
$string = $fraction = null;
if (strpos($number, '.') !== false) {
list($number, $fraction) = explode('.', $number);
}
switch (true) {
case $number < 21:
$string = $dictionary[$number];
break;
case $number < 100:
$tens = ((int) ($number / 10)) * 10;
$units = $number % 10;
$string = $dictionary[$tens];
if ($units) {
$string .= $hyphen . $dictionary[$units];
}
break;
case $number < 1000:
$hundreds = $number / 100;
$remainder = $number % 100;
$string = $dictionary[$hundreds] . ' ' . $dictionary[100];
if ($remainder) {
$string .= $conjunction . convert_number_to_words($remainder);
}
break;
default:
$baseUnit = pow(1000, floor(log($number, 1000)));
$numBaseUnits = (int) ($number / $baseUnit);
$remainder = $number % $baseUnit;
$string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit];
if ($remainder) {
$string .= $remainder < 100 ? $conjunction : $separator;
$string .= convert_number_to_words($remainder);
}
break;
}
if (null !== $fraction && is_numeric($fraction)) {
$string .= $decimal;
$words = array();
foreach (str_split((string) $fraction) as $number) {
$words[] = $dictionary[$number];
}
$string .= implode(' ', $words);
}
return $string;
}
?>
The below code is working fine
$test = 1000025.05;
$f = new \NumberFormatter( locale_get_default(), \NumberFormatter::SPELLOUT );
$word = $f->format($test);
echo $word;
protected function numberTextHelper($number)
{
if (($number < 0) || ($number > 999999999))
{
throw new Exception("Number is out of range");
}
$ones = array("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eightteen", "Nineteen");
$tens = array("", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eigthy", "Ninety");
$giga = floor($number / 1000000);
// Millions (giga)
$number -= $giga * 1000000;
$thousands = floor($number / 1000);
// Thousands (kilo)
$number -= $thousands * 1000;
$hecto = floor($number / 100);
// Hundreds (hecto)
$number -= $hecto * 100;
$deca = floor($number / 10);
// Tens (deca)
$n = $number % 10;
$frac = round($number - (int)$number,2);
// Ones
$result = array();
if ($giga)
{
$result[]= $this->numberTextHelper($giga).' '.($giga>1?'MILLIONS':'MILLION');
}
if ($thousands)
{
$result[]= $thousands>1?$this->numberTextHelper($thousands).' THOUSANDS':'THOUSAND';
}
if ($hecto)
{
$result[]= $this->numberTextHelper($hecto).'HUNDRED';
}
if ($deca)
{
if($deca<2)
{
$result[]= $ones[$deca * 10 + $n];
$n=0;
}
else
{
$result[]= $tens[$deca];
}
}
if ($n)
{
$result[]= $ones[$n];
}
if($frac)
{
$result[]= 'and';
$result[]= $this->numberTextHelper($frac*100);
$result[]= 'cents';
}
if(empty($result))
{
$result[]= 'zero';
}
return implode(' ',$result);
}
And you can translate it
function numberText($number)
{
$result=$this->numberTextHelper($number);
$result=$this->strtoupper($result);
$text=array_filter(explode(' ',$result));
$translated=array_map(array($this,'getLang'),$text);
return implode(' ',$translated);
}