moneyphp / money

PHP implementation of Fowler's Money pattern.
http://moneyphp.org
MIT License
4.62k stars 440 forks source link

Leading zeros. Confusing amount after parsing and formatting #754

Closed ArFeRR closed 10 months ago

ArFeRR commented 1 year ago

Hello everyone!

I've encountered the confusing behavior with parsing numbers, starting from leading zeros. Like "003", "0003" and so on. When you pass "003" to DecimalMoneyParser, it makes Money object with amount "3", which equals to "0.03" after formatting. When you pass "0003" to it, it makes Money object with amount zero. (why?) I expect passing "003" should be "3" after formatting, so the amount inside Money object should be 300. Am I right? Regarding "0003" - I expect this also to be "3", as it's the way how intval(), floatval(), etc. default number functions process numeric values with leading zeros.

Please check the snippet below for better understanding:

<?php
//require your autoload file or make require_once for used classes manually

use Money\Currencies\ISOCurrencies;
use Money\Currency;
use Money\Parser\DecimalMoneyParser;
use Money\Formatter\DecimalMoneyFormatter;

$decimalMoneyParser = new DecimalMoneyParser(new ISOCurrencies());
$decimalMoneyFormatter = new DecimalMoneyFormatter(new ISOCurrencies());

$money = $decimalMoneyParser->parse('003', new Currency('USD'));
var_dump($money->getAmount()); //3 (should be 300)
$result = $decimalMoneyFormatter->format($money); //0.03
var_dump($result); //0.03 (should be 3);
var_dump(intval('003')); //3 - correct!
frederikbosch commented 10 months ago

Maybe you are on an older version, because the following script.

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Money\Currencies\ISOCurrencies;
use Money\Currency;
use Money\Parser\DecimalMoneyParser;
use Money\Formatter\DecimalMoneyFormatter;

$decimalMoneyParser = new DecimalMoneyParser(new ISOCurrencies());
$decimalMoneyFormatter = new DecimalMoneyFormatter(new ISOCurrencies());

$money = $decimalMoneyParser->parse('003', new Currency('USD'));
var_dump($money->getAmount()); //3 (should be 300)
$result = $decimalMoneyFormatter->format($money); //0.03
var_dump($result); //0.03 (should be 3);
var_dump(intval('003')); //3 - correct!

gives me this output.

/usr/bin/php8.1 /srv/libraries/money/test.php
/srv/libraries/money/test.php:13:
string(3) "300"
/srv/libraries/money/test.php:15:
string(4) "3.00"
/srv/libraries/money/test.php:16:
int(3)

I added a test for this specific situation in 6fcdcaf.