-
-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non decimal currencies are not properly supported #51
Comments
Hi, thanks for bringing this to my attention!
This list defines <CcyNtry>
<CtryNm>MADAGASCAR</CtryNm>
<CcyNm>Malagasy Ariary</CcyNm>
<Ccy>MGA</Ccy>
<CcyNbr>969</CcyNbr>
<CcyMnrUnts>2</CcyMnrUnts>
</CcyNtry> As you can see, it defines the currency minor units as 2 decimals, which is the value used in I understand that this may not be of practical use, but if ISO defines it this way, there is probably a reason, and I'm not sure if it would make sense for me to start deviating from the values provided by the ISO standard, at least for the default behaviour: maintaining a up-to-date list of currencies could become a nightmare. Now that doesn't mean that the library should not allow a different usage that deviates from what the ISO standard tells us! Regarding the subdivision 1 ariary = 5 iraimbilanja, would this be just an example of cash rounding? As per the example in the README, the Swiss Franc has a minor unit of For use Brick\Money\Money;
use Brick\Money\Context\CashContext;
use Brick\Math\RoundingMode;
$money = Money::of(10, 'MGA', new CashContext(20)); // MGA 10.00
$money->dividedBy(3, RoundingMode::DOWN); // MGA 3.20
$money->dividedBy(3, RoundingMode::UP); // MGA 3.40 Does that make any sense? Could you give my the expected formatted output for 1 ariary + 2 iraimbilanja, for example? (what The approach uses by dinero.js is very interesting though, I'll look into it. Quoting their docs:
This is definitely not possible using |
Indeed, I'm aware the list shows "2" in this column but it's here just for the sake of filling this column with something. It doesn't mean it's a decimal currency with a 1:100 ratio as Wikipedia says I think it's reasonable to implement the two current exceptions that exists if you want the library to properly support ISO_4217 currencies. Non decimal currencies circulating tend to disappear anyway so there's a high chance it will be a one off job without opening ways to any future maintenance burden. I don't think cash context is the solution as it's unrelated to the fact that formating money to
Well this is the problem we tried to solve in dinero and we settled on having 2 output formats. An "amount and currency" one which is the default as it covers all the type of currencies, even one with multiple minor units. That would give And a second "decimal" output that you explicitly need to call like If you're open to the idea I could try implementing it. |
@tigitz Thank you for the detailed explanation. If we can trust the Wikipedia article that the Mauritanian ouguiya and the Malagasy ariary are the only 2 currencies that are non-decimal, then I'm open to make an exception for these (if you find another source for this information, that would make me a bit more confident though). As I said I'm slightly worried to override the values provided by the ISO standard, but if that is the only way to make the library useful to users of these currencies, I'm in. (That being said, I would really like to understand why ISO did express minor units in terms of "number of decimals", vs "number of minor units". If they said "USD = 100", "MGA = 5", that would have solved the problem for non-decimal currencies, and prevented them from propagating false information. But that's another story I guess.) Please feel free to start working on this, but be aware that this a rather large work with a large potential for breaking changes, so the architecture should probably be discussed first. In particular, this means that we don't represent the value as a That's a lot of questions. Anyway, ideas (and implementations) welcome! 👍 |
As I was helping a friend designing a money library in javascript (dinero.js), I tried to find how non decimal currencies were solved in PHP libraries, as it's the language I'm most familiar. I ended up stumbling upon yours.
Problem is point 4 of the "Falsehoods programmers believe about prices" list.
We struggled on supporting non decimal currencies and I realised
brick\money
currently doesn't support them at all.As stated here, 1 Ariary (unit) = 5 iraimbilanja (minor unit).
However
brick\money
gives 1 Ariary (unit) = 100 iraimbilanja (minor unit)Non decimal currencies has some major implications, formatters for example won't be able to represent the whole amount in a decimal fashion.
Here's some content that could contribute to your own solution:
https://v2.dinerojs.com/docs/core-concepts/currency#currency-base
dinerojs/dinero.js#294 (comment)
The text was updated successfully, but these errors were encountered: