kwn / number-to-words Goto Github PK
View Code? Open in Web Editor NEWNumber to string standalone PHP library with i18n. Drivers for numbers and currency included.
License: MIT License
Number to string standalone PHP library with i18n. Drivers for numbers and currency included.
License: MIT License
Hi I'm trying to install this library but I always get this error. How can I solve it?
An uncaught Exception was encountered
Type: ParseError
Message: syntax error, unexpected 'array' (T_ARRAY), expecting function (T_FUNCTION) or const (T_CONST)
Filename: /var/www/clients/client0/web14/web/application/vendor/kwn/number-to-words/src/Concerns/ManagesCurrencyTransformers.php
Hello,
Please, is it possible to add, for the French language, the currency
"Mauritian Rupee" (MUR).
Fr.php, $currencyNames = [ ... , 'MUR' => [['roupie mauricienne'], ['cents']],]
Thanks :)
If I want convert 4354.12 to words?
Bloody German ;)
It should be, e.g.
ein US Dollar
instead of
eins US Doller
(while formatting 1 US Dollar)
Could you add this currency please
GTQ: quetzales
We use this package in production and we found an issue with it.
Here the tested code :
(new NumberToWords())
->getCurrencyTransformer('fr')
->toWords(1000, 'JPY')
;
Here the raised error : "Array to string conversion"
Notice that it works with 100 => "un yen"
But not with 101 for instance => "Undefined offset: 1"
Can you fix it, please ?
As a complementary remark, it will be a great addition to have a method that return the supported combinaison between Currency and Langage.
Best regards.
Please add Bulgarian Currency!
So in #2 we briefly talked about how someone might use this library. Let's talk first about how to use it now. An example:
//build the registry of transformers we want to work with
$registry = new TransformerFactoriesRegistry([
new EnglishTransformerFactory
]);
//create the number to words "manager" class
$numberToWords = new NumberToWords($registry);
//build a new currency transformer
$currencyTransformer = $numberToWords->getCurrencyTransformer('en', 'USD', SubunitFormat::Words);
//build an Amount that we can pass to the transformer
$amount = new Amount(new Number(50), new Currency('USD'), new SubunitFormat(SubunitFormat::Words));
//do the conversion
$currencyTransformer->toWords($amount); //outputs "fifty dollars and zero cents"
So as a first point, I think we should decide where the currency and subunit format information should live. In the above code, this line:
$numberToWords->getCurrencyTransformer('en', 'USD', SubunitFormat::Words);
Is a bit deceptive because it's not actually creating an English, US Dollar, subunit word transformer. It's creating an English transformer that can convert any Amount
into words. The Amount
has meta information about its currency and subunit format. I think what's obvious is that the subunit format shouldn't be a part of the Amount
because it doesn't really describe the amount, but the transformation that needs to occur. A similar argument could be made for the currency...it's simple a facet of how you convert a particular number into words.
So if we split these concepts off into the transformer creation, we can simplify the data structures a bit:
//this now uses the second and third parameters to instruct the transformer creation
$currencyTransformer = $numberToWords->getCurrencyTransformer('en', 'USD', SubunitFormat::Words);
//do the conversion
$currencyTransformer->toWords(new Number(50)); //outputs "fifty dollars and zero cents"
The one downside of this is that it puts a bit more work up to the service registration layer (i.e. you need to explicitly create an English, USD, subunit word transformer instead of having a more flexible transformer that can be used in a bunch of different ways). However, I think a decently-architected system won't have to worry about this as the transformer dependency needs to be explicitly created anyway.
So then maybe we can do one better by eliminating the Number
:
$currencyTransformer->toWords(50); //outputs "fifty dollars and zero cents"
$currencyTransformer->toWords(49.99); //outputs "forty nine dollars and ninety nine cents"
We could still convert that int/float to a Number
in the transformer, of course.
Let me know what you think..
\Kwn\NumberToWords\Language\Romanian\Transformer\CurrencyTransformer.php at line 53
$ret .= ' ' . $this->toWords($fraction, $currNouns[1]);
should actually be
$ret .= ' ' . $this->transformer->toWords($fraction, $currNouns[1]);
Hello.
I find this library amazing. I'm trying to convert currency to text, which for the language that i have chosen "bg" is not created, but thats ok - i can use the numbers convertor. I've checked the source code and there are 3 different forms .By default it is set to the neutral digit, but I need to use the masculine form. Is there some way to change it ?
private static $digits = [
0 => [1 => "едно", "две", "три", "четири", "пет", "шест", "седем", "осем", "девет"], // neuter
1 => [1 => 'един', 'два'], // masculine
-1 => [1 => 'една'] // feminine
];
The only code I use ( and this is an example ) is
$numberToWords = new \NumberToWords\NumberToWords;
$trans = $numberToWords->getNumberTransformer('bg');
$trans->toWords(2011);
If there is no option to toggle this, is there a way for me to extend the library and do it on my own
tldr. i need to have "един" and "два" Instead of "едно" and "две".
Currently, number transformer generates string devádesát
from number 90. However, correct wording is without punctutation above first letter a
=> devadesát
cast "(float) $value" from Number model cuts currency fraction for example:
->toWords(50.99) // works correctly
->toWords(50.90) //does not works correctly cuts currency to 50.9 and displays pięćdziesiąt złotych dziewięć groszy
Many thanks for this nice piece of code!
However: I am pretty sure that in German the minus is spelled out separated by a space and in lowercase. But of course: being a German I still may be wrong though the stock PHP NumberFormatter also handles it that way. So it probably should be:
minus fünfzehn
instead of the Minusfünfzehn
(i.e. spelled out -15 in German).
I've been trying to use the exponent separator, but it doesn't seem to be used anywhere in code (except for it's initialization in a function).
Is the purpose of exponentSeparator to separate triplets with a string?
I need to have next output "pięćdziesiąt złotych 98 groszy".
I try use this library as describe in README and get next result "piecdziesiat zlotych 98/100"
$registry = new \Kwn\NumberToWords\Transformer\TransformerFactoriesRegistry([
new \Kwn\NumberToWords\Language\Polish\TransformerFactory()
]);
$numberToWords = new \Kwn\NumberToWords\NumberToWords($registry);
$currencyTransformer = $numberToWords->getCurrencyTransformer('pl', 'PLN', \Kwn\NumberToWords\Model\SubunitFormat::NUMBERS);
var_dump($currencyTransformer->toWords(50.98));
// piecdziesiat zlotych 98/100
What does actually mean this "98/100"?
P.S. I has added support for Ukrainian and Russian languages but before to do PR I want understand how to implement this feature in correct way.
Hi.
just a little issue. in brazilian portuguese the character ü in word cinqüenta is not used anymore. now it's just the character 'u'
please, change cinqüenta to cinquenta in file \src\Legacy\Numbers\Words\Locale\Pt\BR.php
Thanks!
Also add currency 'INR' with Language 'hindi'
The numer 14 is in an informal form.
correct form : patrusprezece
Currencies below than zero does not display correctly. I propose add minus sign property to Number model or/and use abs function to convert currency correctly.
Hi! I am very interested in your library, however - we also work with the Chinese language, and I would like to see the localization of zh_ZH. Can you tell me if it is planned to be added? Or, can I finalize this localization myself, and create a PR for you? Thanks!
Please try to add Indian Currency
First, thank you for your work.
If you use one of the supplied transformers (for example, GermanCurrencyTransformer), there is no way to modify the NumberTransformerBuilder. In my case, I need to customize the "withWordsSeparatedBy()" method, but the rest should stay the same.
Perhaps the CurrencyTransformer interface could get a "getTransformerBuilder()" method so that I can override this method to provde a custom provider in a child class.
Here is a simple example:
class CustomizedGermanCurrencyTransformer extends GermanCurrencyTransformer {
/**
* Overrides the default transformer builder to modify builder options
*
* @return \NumberToWords\NumberTransformer\NumberTransformer
*/
public function getTransformerBuilder()
{
return $numberTransformer = (new NumberTransformerBuilder())
->withDictionary($dictionary)
->withWordsSeparatedBy('')
->transformNumbersBySplittingIntoPowerAwareTriplets($numberToTripletsConverter, $tripletTransformer)
->inflectExponentByNumbers($exponentInflector)
->build();
}
}
Number: 2342535345365393436
:
Expected:
два секстиллиона триста сорок два квадриллиона пятьсот тридцать пять триллионов триста сорок пять миллиардов триста шестьдесят пять миллионов триста девяноста три тысячи четыреста тридцать шесть
Actual:
два секстиллиона триста сорок два квадриллиона пятьсот тридцать пять триллионов триста сорок пять миллиардов триста шестьдесят пять миллионов триста девяносто три тысячи четыреста восемь
Second number: 5342535345365393436
:
Expected:
пять секстиллионов триста сорок два квадриллиона пятьсот тридцать пять триллионов триста сорок пять миллиардов триста шестьдесят пять миллионов триста девяноста три тысячи четыреста тридцать шесть
Actual:
пять секстиллионов триста сорок два квадриллиона пятьсот тридцать пять триллионов триста сорок пять миллиардов триста шестьдесят пять миллионов триста девяносто три тысячи четыреста восемь
When a number ends with 1 the conversion is "....uno pesos" => should be "...un pesos"
when the number is one, the conversion is "uno peso" => should be "un peso"
you could use this https://github.com/juliendb/NumberToString/blob/master/NumberToString.php as a start for dictionary
please there is no Arabic support in this module
Hi, I looked into your package and realized the "toWords()" method was missing, Kindly assist!!
Hello,
How are you,
Will it be possible to add Breton language to this project?
Regards
Pierre
Hi folks.
I Like the idea of supporting multiple languages in single library. So just tried ti implement Persian based on English classes.
It turned out its not possible to do such using current GenericNumberTransformerBuilder
and it needs some modifications ( Adding another property like $tripletSeparator
and modifying some parts might solve this but seems overkill to me).
I spent last couple of hours and made a number to words translator from scratch for Persian language. It has same test suite as english test and it is passing.
So was wondering if you have any interests in me creating a NumberTransformer
wrapper for this language-specific implementation and make a pull request.
Could you please include a license?
I am trying to convert money to words. But I don't know what happen with this number: 584.93 The library show me: Five Hundred Eighty-Four Dollars Ninety-Two Cents.
use NumberToWords\NumberToWords;
$numberToWords = new NumberToWords();
$currencyTransformer = $numberToWords->getCurrencyTransformer('en')->toWords(584.93*100, 'USD');
echo $currencyTransformer;
It is not ninety-two. It is ninety-three. Why does this happen?
Examples:
шістдесят долларов США п'ятдесят центов
шістдесят злотых п'ятдесят грошей
There is no letter ы
in Ukrainian.
First Of All Congrat and Thank you ForThe usefull Library ;
Just Notice That FrenchCurrencyTransformer is not Present in NumberToWords Class on the $currencyTransformers , wich lead to an error " Currency transformer for "fr" language is not implemented "
CHF translation must be 'İsviçre frankı' in Turkish.
when use this package with project that have dynamic currencies, and user add new currency not supported by this package it will throw exception "Currency "%s" is not available for "%s" language",
I think if we return an empty array it will be better.
'UAH' => [ [2, 'гривна', 'гривны', 'гривен'], [1, 'цент', 'цента', 'центов']
1 UAH = 100 копеек, is called as well as a Russian kopeyka
You should change [ 'цент', 'цента', 'центов'] to [ 'копейка', 'копейки', 'копеек']
I have a use case where I convert 1.16 to words in es, I get "un peso con quince centavos" that is wrong, I expected "un peso con dieciseis centavos", then the result is 0.01 less than required, when I read the code I found in Numbers/Words.php file the follow method:
public function transformToCurrency($amount, $locale, $currency)
{
$localeClassName = $this->resolveLocaleClassName($locale);
$transformer = new $localeClassName($this->options);
$decimalPart = (int) ($amount / 100);
$fractionalPart = $amount % 100;
if (0 === $fractionalPart) {
return trim($transformer->toCurrencyWords($currency, $decimalPart));
}
return trim($transformer->toCurrencyWords($currency, $decimalPart, $fractionalPart));
}
I found it right and checking in http://phptester.net/ it works right but when I run mi app I get 15 instead of 16 by the fractional part, when I replace with fmod() I get the right value, I don't know the risk of this, but, the fractional part could be calculate by some kind of:
public function transformToCurrency($amount, $locale, $currency)
{
$localeClassName = $this->resolveLocaleClassName($locale);
$transformer = new $localeClassName($this->options);
$decimalPart = (int) ($amount / 100);
$fractionalPart = $amount - ($decimalPart * 100); // <-- suggestion
if (0 === $fractionalPart) {
return trim($transformer->toCurrencyWords($currency, $decimalPart));
}
return trim($transformer->toCurrencyWords($currency, $decimalPart, $fractionalPart));
}
I'm working with php7.2/7.3
edit:
The same is happening in Locale/Es.php in
$d = $number % 10; // <- line 141
$t = (int) ($number / 10) % 10;
$h = (int) ($number / 100) % 10;
Using v1.9.2 or v1.12.0, numbers 64.74, 65.74, 66.74 etc. up to 81.74 are all given decimal words of 73 instead of 74, that is 'seventy-three' in English (or 'soixante treize' in French which I use) in whatever currency selected.
I am struggling with using the same for INR currency.
I am searching for a way to set currencyNames to 'INR' => [['Rupees'], ['paisa']],
Hey, could you create releses tags with major changes in the package?
how to force write zero fraction, so if i have 144.00 USD i get the fallowing
$currencyTransformer->toWords(14400, 'USD');
one hundred forty-four dollar.
i want to get
one hundred forty-four dollar and zero cent .
Hi everyone, thanks for the work that you all have put in this library. I am not using docker and when I start calling the method to get the transformer I get a cascade of error. I was wondering whether you could implement an autoloader or if there is a quick way to solve all these "Class not found" errors.
I tried implementing an autoloader but with poor results (I am not an expert in php).
Thank you for your time.
Is there any way to achieve the following?
5250.31 => five thousand two hundred and fifty with 31/100 US dollars
Thanks in advance.
Hi, found little bug in
/src/Legacy/Numbers/Words/Locale/Ua.php
In Ukrainian, const MINUS must be "мінус".
The documentation is slightly incorrect, you need to instciate it with the namespace:
$numberToWords = new NumberToWords();
It should be:
$numberToWords = new NumberToWords\NumberToWords();
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.