-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added Swahili language * Updated README to fit swahili * Improved kiswahili grammar * Added Swahili tests * Added Swahili
- Loading branch information
Showing
10 changed files
with
444 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ | |
/build/ | ||
/composer.lock | ||
*.cache | ||
test.php |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace NumberToWords\CurrencyTransformer; | ||
|
||
use NumberToWords\Legacy\Numbers\Words; | ||
use NumberToWords\TransformerOptions\CurrencyTransformerOptions; | ||
|
||
class SwahiliCurrencyTransformer implements CurrencyTransformer | ||
{ | ||
public function toWords(int $amount, string $currency, ?CurrencyTransformerOptions $options = null): string | ||
{ | ||
$converter = new Words($options); | ||
|
||
return $converter->transformToCurrency($amount, 'sw', $currency); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
<?php | ||
|
||
namespace NumberToWords\Legacy\Numbers\Words\Locale; | ||
|
||
use NumberToWords\Legacy\Numbers\Words; | ||
use NumberToWords\Exception\NumberToWordsException; | ||
|
||
class Sw extends Words | ||
{ | ||
private static $miscNumbers = [ | ||
10 => 'kumi', | ||
20 => 'ishirini', | ||
30 => 'thelathini', | ||
40 => 'arobaini', | ||
50 => 'hamsini', | ||
60 => 'sitini', | ||
70 => 'sabini', | ||
80 => 'themanini', | ||
90 => 'tisini', | ||
100 => 'mia' | ||
]; | ||
|
||
private static $digits = [ | ||
1 => 'moja', | ||
2 => 'mbili', | ||
3 => 'tatu', | ||
4 => 'nne', | ||
5 => 'tano', | ||
6 => 'sita', | ||
7 => 'saba', | ||
8 => 'nane', | ||
9 => 'tisa' | ||
]; | ||
|
||
private static $exponent = [ | ||
0 => '', | ||
3 => 'elfu', | ||
5 => 'laki', | ||
6 => 'milioni', | ||
9 => 'bilioni', | ||
12 => 'trilioni', | ||
]; | ||
|
||
private $zero = 'sifuri'; | ||
private $and = 'na'; | ||
private $wordSeparator = ' '; | ||
private $minus = 'kasoro'; | ||
|
||
// Currency names | ||
private static $currencyNames = [ | ||
'KES' => [['Shilingi ya Kenya', 'Shilingi za Kenya'], ['senti', 'senti']], | ||
'USD' => [['Dola ya Marekani', 'Dola za Marekani'], ['senti', 'senti']], | ||
'EUR' => [['Yuro', 'Yuro'], ['senti', 'senti']], | ||
'GBP' => [['Pauni ya Uingereza', 'Pauni za Uingereza'], ['senti', 'senti']], | ||
'TZS' => [['Shilingi ya Tanzania', 'Shilingi za Tanzania'], ['senti', 'senti']], | ||
'UGX' => [['Shilingi ya Uganda', 'Shilingi za Uganda'], ['senti', 'senti']], | ||
'ZAR' => [['Randi ya Afrika Kusini', 'Randi za Afrika Kusini'], ['senti', 'senti']], | ||
'NGN' => [['Naira ya Nigeria', 'Naira za Nigeria'], ['kobo', 'kobo']], | ||
'GHS' => [['Cedi ya Ghana', 'Cedi za Ghana'], ['Pesewa', 'Pesewa']], | ||
'RWF' => [['Faranga ya Rwanda', 'Faranga za Rwanda'], ['senti', 'senti']], | ||
'BWP' => [['Pula ya Botswana', 'Pula za Botswana'], ['thebe', 'thebe']], | ||
'INR' => [['Rupia ya India', 'Rupia za India'], ['paise', 'paise']], | ||
'JPY' => [['Yen ya Japani', 'Yen za Japani'], ['seni', 'seni']], | ||
'CNY' => [['Yuan ya China', 'Yuan za China'], ['feni', 'feni']], | ||
'CAD' => [['Dola ya Kanada', 'Dola za Kanada'], ['senti', 'senti']], | ||
'AUD' => [['Dola ya Australia', 'Dola za Australia'], ['senti', 'senti']], | ||
'CHF' => [['Faranga ya Uswisi', 'Faranga za Uswisi'], ['senti', 'senti']], | ||
'BRL' => [['Reali ya Brazil', 'Reali za Brazil'], ['sentavo', 'sentavo']], | ||
'MXN' => [['Peso ya Meksiko', 'Peso za Meksiko'], ['sentavo', 'sentavo']], | ||
'SAR' => [['Riyal ya Saudi Arabia', 'Riyal za Saudi Arabia'], ['halala', 'halala']], | ||
'AED' => [['Dirham ya Umoja wa Falme za Kiarabu', 'Dirham za Umoja wa Falme za Kiarabu'], ['fils', 'fils']], | ||
'EGP' => [['Pauni ya Misri', 'Pauni za Misri'], ['piastiri', 'piastiri']], | ||
]; | ||
|
||
|
||
|
||
protected function toWords($number) | ||
{ | ||
if ($number == 0) { | ||
return $this->zero; | ||
} | ||
|
||
$isNegative = $number < 0; | ||
$number = abs($number); | ||
|
||
// Handle decimal numbers | ||
$integerPart = floor($number); | ||
$decimalPart = $number - $integerPart; | ||
|
||
$result = $this->convertIntegerPart($integerPart); | ||
|
||
if ($decimalPart > 0) { | ||
$result .= ' nukta ' . $this->convertDecimalPart($decimalPart); | ||
} | ||
|
||
if ($isNegative) { | ||
$result = $this->minus . $this->wordSeparator . $result; | ||
} | ||
|
||
return trim($result); | ||
} | ||
|
||
private function convertIntegerPart($number) | ||
{ | ||
$result = ''; | ||
|
||
if ($number >= 1000000000000) { | ||
$trillions = floor($number / 1000000000000); | ||
$result .= self::$exponent[12] . $this->wordSeparator . $this->numberToSwahiliLessThanThousand($trillions) . ', '; | ||
$number %= 1000000000000; | ||
} | ||
|
||
if ($number >= 1000000000) { | ||
$billions = floor($number / 1000000000); | ||
$result .= self::$exponent[9] . $this->wordSeparator . $this->numberToSwahiliLessThanThousand($billions) . ', '; | ||
$number %= 1000000000; | ||
} | ||
|
||
if ($number >= 1000000) { | ||
$millions = floor($number / 1000000); | ||
$result .= self::$exponent[6] . $this->wordSeparator . $this->numberToSwahiliLessThanThousand($millions) . ', '; | ||
$number %= 1000000; | ||
} | ||
|
||
if ($number >= 100000) { | ||
$lakhs = floor($number / 100000); | ||
$result .= self::$exponent[5] . $this->wordSeparator . $this->numberToSwahiliLessThanHundredThousand($lakhs) . ', '; | ||
$number %= 100000; | ||
} | ||
|
||
if ($number >= 1000) { | ||
$thousands = floor($number / 1000); | ||
$result .= self::$exponent[3] . $this->wordSeparator . $this->numberToSwahiliLessThanThousand($thousands) . ', '; | ||
$number %= 1000; | ||
} | ||
|
||
if ($number > 0) { | ||
$result .= $this->numberToSwahiliLessThanThousand($number); | ||
} | ||
|
||
return rtrim(rtrim($result), ','); | ||
} | ||
|
||
private function convertDecimalPart($decimal) | ||
{ | ||
$decimalStr = substr(strval($decimal), 2); // Remove "0." | ||
$result = ''; | ||
foreach (str_split($decimalStr) as $digit) { | ||
$result .= $this->numberToSwahiliLessThanTen((int)$digit) . $this->wordSeparator; | ||
} | ||
return trim($result); | ||
} | ||
|
||
private function numberToSwahiliLessThanTen($number) | ||
{ | ||
return self::$digits[$number]; | ||
} | ||
|
||
private function numberToSwahiliLessThanHundred($number) | ||
{ | ||
if ($number < 10) { | ||
return $this->numberToSwahiliLessThanTen($number); | ||
} | ||
|
||
$tens = array_values(self::$miscNumbers); | ||
$ten = floor($number / 10); | ||
$one = $number % 10; | ||
|
||
$result = $tens[$ten - 1]; | ||
if ($one > 0) { | ||
$result .= $this->wordSeparator . $this->and . $this->wordSeparator . $this->numberToSwahiliLessThanTen($one); | ||
} | ||
|
||
return $result; | ||
} | ||
|
||
private function numberToSwahiliLessThanThousand($number) | ||
{ | ||
if ($number < 100) { | ||
return $this->numberToSwahiliLessThanHundred($number); | ||
} | ||
|
||
$hundred = floor($number / 100); | ||
$remainder = $number % 100; | ||
|
||
$result = ($hundred == 1) ? self::$miscNumbers[100] : self::$miscNumbers[100] . $this->wordSeparator . $this->numberToSwahiliLessThanTen($hundred); | ||
if ($remainder > 0) { | ||
$result .= $this->wordSeparator . $this->and . $this->wordSeparator . $this->numberToSwahiliLessThanHundred($remainder); | ||
} | ||
|
||
return $result; | ||
} | ||
|
||
private function numberToSwahiliLessThanHundredThousand($number) | ||
{ | ||
if ($number < 1000) { | ||
return $this->numberToSwahiliLessThanThousand($number); | ||
} | ||
|
||
$thousand = floor($number / 1000); | ||
$remainder = $number % 1000; | ||
|
||
$result = ($thousand == 1) ? self::$exponent[3] : self::$exponent[3] . $this->wordSeparator . $this->numberToSwahiliLessThanThousand($thousand); | ||
if ($remainder > 0) { | ||
$result .= $this->wordSeparator . $this->and . $this->wordSeparator . $this->numberToSwahiliLessThanThousand($remainder); | ||
} | ||
|
||
return $result; | ||
} | ||
|
||
public function toCurrencyWords($currency, $decimal, $fraction = null) | ||
{ | ||
$currency = strtoupper($currency); | ||
|
||
if (!array_key_exists($currency, static::$currencyNames)) { | ||
throw new NumberToWordsException( | ||
sprintf('Currency "%s" is not available for Swahili language', $currency) | ||
); | ||
} | ||
|
||
$currencyNames = static::$currencyNames[$currency]; | ||
$return = trim($this->toWords($decimal)); | ||
|
||
// Check if singular and plural forms are available | ||
$level = ($decimal === 1) ? 0 : 1; | ||
$currencySingularOrPlural = isset($currencyNames[0][$level]) ? $currencyNames[0][$level] : ''; | ||
|
||
$return = $currencySingularOrPlural. $this->wordSeparator.$return; | ||
|
||
if (null !== $fraction) { | ||
|
||
$level = $fraction === 1 ? 0 : 1; | ||
|
||
// Check if singular and plural forms for fraction are available | ||
$fractionSingularOrPlural = isset($currencyNames[1][$level]) ? $currencyNames[1][$level] : ''; | ||
|
||
$return .= sprintf( | ||
'%1$s%2$s%1$s%3$s', | ||
$this->wordSeparator, | ||
$this->and.' '.$fractionSingularOrPlural, | ||
trim($this->toWords($fraction)) | ||
); | ||
} | ||
|
||
return trim(ucfirst($return)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
namespace NumberToWords\NumberTransformer; | ||
|
||
use NumberToWords\Legacy\Numbers\Words; | ||
|
||
class SwahiliNumberTransformer implements NumberTransformer | ||
{ | ||
public function toWords(int $number): string | ||
{ | ||
$converter = new Words(); | ||
|
||
return $converter->transformToWords($number, 'sw'); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
tests/CurrencyTransformer/SwahiliCurrencyTransformerTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
namespace NumberToWords\CurrencyTransformer; | ||
|
||
class SwahiliCurrencyTransformerTest extends CurrencyTransformerTest | ||
{ | ||
protected function setUp(): void | ||
{ | ||
$this->currencyTransformer = new SwahiliCurrencyTransformer(); | ||
} | ||
|
||
public function providerItConvertsMoneyAmountToWords(): array | ||
{ | ||
return [ | ||
[6474, 'USD', 'Dola za Marekani sitini na nne na senti sabini na nne'], | ||
[6574, 'USD', 'Dola za Marekani sitini na tano na senti sabini na nne'], | ||
[8174, 'USD', 'Dola za Marekani themanini na moja na senti sabini na nne'], | ||
[8255, 'KES', 'Shilingi za Kenya themanini na mbili na senti hamsini na tano'], | ||
[72900, 'USD', 'Dola za Marekani mia saba na ishirini na tisa'], | ||
[89400, 'USD', 'Dola za Marekani mia nane na tisini na nne'], | ||
[99900, 'TZS', 'Shilingi za Tanzania mia tisa na tisini na tisa'], | ||
[100000, 'USD', 'Dola za Marekani elfu moja'], | ||
[100100, 'USD', 'Dola za Marekani elfu moja, moja'], | ||
[109725, 'GBP', 'Pauni za Uingereza elfu moja, tisini na saba na senti ishirini na tano'], | ||
[110400, 'USD', 'Dola za Marekani elfu moja, mia na nne'], | ||
[124380, 'EUR', 'Yuro elfu moja, mia mbili na arobaini na tatu na senti themanini'], | ||
[238500, 'USD', 'Dola za Marekani elfu mbili, mia tatu na themanini na tano'], | ||
[376600, 'USD', 'Dola za Marekani elfu tatu, mia saba na sitini na sita'], | ||
[584600, 'USD', 'Dola za Marekani elfu tano, mia nane na arobaini na sita'], | ||
[645900, 'USD', 'Dola za Marekani elfu sita, mia nne na hamsini na tisa'], | ||
[723200, 'USD', 'Dola za Marekani elfu saba, mia mbili na thelathini na mbili'], | ||
[-72925, 'UGX', 'Shilingi za Uganda kasoro mia saba na ishirini na tisa na senti ishirini na tano'], | ||
[-89425, 'USD', 'Dola za Marekani kasoro mia nane na tisini na nne na senti ishirini na tano'], | ||
[-99925, 'USD', 'Dola za Marekani kasoro mia tisa na tisini na tisa na senti ishirini na tano'], | ||
]; | ||
} | ||
} |
Oops, something went wrong.