[PHP] Jak zamienić liczby na kwoty zapisane słownie, np. "117 = sto siedemnaście złotych"?
Chcesz zamienić liczby na liczebniki. Największa liczba jaką można uzyskać to jeden miliard dwieście piętnaście milionów siedemset pięćdziesiąt trzy tysiące dwieście dziewięćdziesiąt trzy złote.
Zamiana liczby na jej postać słowną przydaje się m.in. podczas tworzenia faktur online i wszędzie tam, gdzie zapis słowny jest wymagany lub po prostu przydatny.
Słowna reprezentacja kwoty eliminuje pomyłki, jeżeli liczba jest duża lub trudno ją szybko ogarnąć wzrokiem. Stąd tak bardzo przydaje się skrypt, który potrafi zamienić liczbę na słowa. Zobacz jak tego dokonać.
<?
function policz($l,$t1,$t2,$t3) {
$j = array("", "jeden ", "dwa ", "trzy ", "cztery ", "pięć ", "sześć ",
"siedem ", "osiem ", "dziewięć ", "dziesięć ", "jedenaście ",
"dwanaście ", "trzynaście ", "czternaście ", "piętnaście ",
"szesnaście ", "siedemnaście ", "osiemnaście ", "dziewiętnaście ");
$d = array("", "", "dwadzieścia ", "trzydzieści ", "czterdzieści ",
"pięćdziesiąt ", "sześćdziesiąt ", "siedemdziesiąt ",
"osiemdziesiąt ", "dziewięćdziesiąt ");
$s = array("","sto ", "dwieście ", "trzysta ", "czterysta ", "pięćset ",
"sześćset ", "siedemset ", "osiemset ", "dziewięćset ");
$txt = $s[0+substr($l,0,1)];
if (substr($l,1,2)<20) $txt .= $j[0+substr($l,1,2)];
else $txt .= $d[0+substr($l, 1,1)].$j[0+substr($l, 2,1)];
if ($l<>0) if ($l==1) $txt .= "$t1 "; else {
if ((substr($l,2,1)==2 or substr($l,2,1)==3 or substr($l,2,1)==4)
and (substr($l,1,2)>20 or substr($l,1,2)<10))
$txt .= "$t2 "; else $txt .= "$t3 ";
}
return $txt;
}
function slownie($liczba) {
$liczba=sprintf("%012d",$liczba);
$txt .= policz(substr($liczba, 0,3),"miliard","miliardy","miliardów");
$txt .= policz(substr($liczba, 3,3),"milion","miliony","milionów");
$txt .= policz(substr($liczba, 6,3),"tysiąc","tysiące","tysięcy");
$txt .= policz(substr($liczba, 9,3),"złoty","złote","złotych");
if ($liczba==0) $txt="zero złotych";
return $txt;
}
echo "<br>10001101 to ".slownie(10001101);
echo "<br>7362 to ".slownie(7362);
echo "<br>9181716 to ".slownie(9181716);
?>
Przykład:
10001101 to dziesięć milionów jeden tysiąc sto jeden złotych
7362 to siedem tysięcy trzysta sześćdziesiąt dwa złote
9181716 to dziewięć milionów sto osiemdziesiąt jeden tysięcy siedemset szesnaście złotych
Zagadnienie jest względnie proste jeżeli chodzi o sam algorytm zamiany liczby na słowa. Przekazana liczba uzupełniana jest o dodatkowe zera wiodące, aby jej długość wynosiła 12 znaków. Tak więc np. 467 zostanie zamieniona na 000000000467.
Wykonując powyższy zabieg łatwo można podzielić liczbę na trójki cyfr - pierwsza reprezentuje miliardy, kolejna miliony, następna tysiące, a ostatnia setki i dziesiątki.
Poszczególne trójki bez problemu można potem zamienić na wartości słowne. Zauważ, że zapis 768 milionów lub 768 tysięcy różni się tylko rzędem wielkości, samo "siedemset sześćdziesiąt osiem" pozostaje bez zmian. To własnie funkcja policz() dokonuje konwersji wybranej trójki na postać słowną i dodaje stosowną odmianę jednostek.
Podczas zamiany należy tylko pamiętać o regułach języka polskiego. Jeżeli cała trójka jest równa 1 to mamy tysiąc, milion, bilion, złoty. Jeżeli koncówka jest 2, 3 lub 4 i nie są to dziesiątki (np. 3422) to wtedy mamy miliony, tysiące, złote, miliardy. W innych przypadkach pozostaje użyć złotych, tysięcy, miliardów czy milionów (np. 611517).
Jeżli liczba jest zerowa wypisujemy "zero złotych".
Niemal identycznie wygląda obsługa groszy, jedynie do funkcji liczba przekazana jest jako ciąg znaków z przecinkiem:
<?
function policz($l,$t1,$t2,$t3) {
$j = array("", "jeden ", "dwa ", "trzy ", "cztery ", "pięć ", "sześć ",
"siedem ", "osiem ", "dziewięć ", "dziesięć ", "jedenaście ",
"dwanaście ", "trzynaście ", "czternaście ", "piętnaście ",
"szesnaście ", "siedemnaście ", "osiemnaście ", "dziewiętnaście ");
$d = array("", "", "dwadzieścia ", "trzydzieści ", "czterdzieści ",
"pięćdziesiąt ", "sześćdziesiąt ", "siedemdziesiąt ",
"osiemdziesiąt ", "dziewięćdziesiąt ");
$s = array("","sto ", "dwieście ", "trzysta ", "czterysta ", "pięćset ",
"sześćset ", "siedemset ", "osiemset ", "dziewięćset ");
$txt = $s[0+substr($l,0,1)];
if (substr($l,1,2)<20) $txt .= $j[0+substr($l,1,2)];
else $txt .= $d[0+substr($l, 1,1)].$j[0+substr($l, 2,1)];
if ($l<>0) if ($l==1) $txt .= "$t1 "; else {
if ((substr($l,2,1)==2 or substr($l,2,1)==3 or substr($l,2,1)==4)
and (substr($l,1,2)>20 or substr($l,1,2)<10))
$txt .= "$t2 "; else $txt .= "$t3 ";
}
return $txt;
}
function slownie($liczba) {
$kwota=explode(",", $liczba);
$kwotazl=sprintf("%012d",$kwota[0]);
$kwotagr=sprintf("%03d",$kwota[1]);
$txt .= policz(substr($kwotazl, 0,3),"miliard","miliardy","miliardów");
$txt .= policz(substr($kwotazl, 3,3),"milion","miliony","milionów");
$txt .= policz(substr($kwotazl, 6,3),"tysiąc","tysiące","tysięcy");
$txt .= policz(substr($kwotazl, 9,3),"złoty","złote","złotych");
if ($kwotazl==0) $txt .= "zero złotych ";
$txt .= " i ";
$txt .= policz($kwotagr,"grosz","grosze","groszy");
if ($kwotagr==0) $txt .= "zero groszy";
return $txt;
}
echo "<br>100011,02 to ".slownie("100011,02");
echo "<br>7362,56 to ".slownie("7362,56");
echo "<br>91817,16 to ".slownie("91817,16");
?>
oto przykład:
100011,02 to sto tysięcy jedenaście złotych i dwa grosze
7362,56 to siedem tysięcy trzysta sześćdziesiąt dwa złote i pięćdziesiąt sześć groszy
91817,16 to dziewięćdziesiąt jeden tysięcy osiemset siedemnaście złotych i szesnaście groszy