Decimal money format - php

how to convert all numbers to xx,xx decimal format without exploding number or string?
like;
8,9 --> 8,90
8,99 --> 8,99
12,1 --> 12,10
129,9 --> 129,90
any idea?

You can use number_format like:
$n = 2.1;
echo number_format($n, 2, ','); // 2,10
If you have commas as decimal separators in your input you can convert values to float with:
$number = floatval(str_replace(',', '.', str_replace('.', '', $string_number)));
str_replace('.', '', $string_number) is used to remove thousand separators.
str_replace(',', '.', ... ) is used to replace commas with dots.

If you have the intl extension enabled, the best approach to the issue (IMO) is given in the accepted answer to this question: PHP: unformat money
You can use
NumberFormatter::parseCurrency - Parse a currency number
Example from Manual:
$formatter = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
var_dump($formatter->parseCurrency("75,25 €", $curr));
gives: float(75.25)
Note that the intl extension is not enabled by default. Please
refer to the Installation Instructions.
After that, you'll have a float value and formatting that is a trivial issue using number_format().
If you do not have that extension, check out the regex approach in this question: What a quick way to clean up a monetary string

$money = number_format($number, 2, ",", ","); // $number must be a float, i.e 8.8
If your inputs have to have commas as decimal separators, do this too:
$money = "20,2";
$fixed_money = floatval(str_replace(",", ".", $money));
echo number_format($fixed_money, 2, ",", ",");

str_pad will add the missing zero
$val = '1008,95';
$len = strpos($val, ',') + 3;
$newval = str_pad($val, $len, '0', STR_PAD_RIGHT);
echo "Value: " . $newval . "<br>";
You have to be sure that your values don't have more than two decimal digits, though

I made a composer package that can deal with such things depending on which currency you are displaying.
https://packagist.org/packages/votemike/money
If you also enter the country it will format the currency in the local way (with or without commas and with the correct number of decimal places)
$money = new Money(99.50, 'JPY');
$money->format(); //¥100
And so if you just create a new money object with the amount you want to display and the currency you are displaying it in, calling ->format() on that object should give you the result you're looking for.

Related

PHP - floatval cuts of position after decimal point?

I have this PHP code:
<?php
$float = "1,99";
echo "<p>$float<br>";
$float = floatval($float); // Without this line number_format throws a notice "A non well formed numeric value encountered" / (float) $float leads to the same output
$val = number_format($float, 2,'.', ',');
echo "$float</p>";
?>
Why does it return 1? Don't get that.
And: yes, there is a sense in converting 1,99 to 1,99 ;-)
Thanks for advise...
The problem is, that PHP does not recognize the , in 1,99 as a decimal separator. The float type is defined as having the following formal definition:
LNUM [0-9]+
DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM [+-]?(({LNUM} | {DNUM}) [eE][+-]? {LNUM})
That means it'll only accept . as a decimal separator. That's in fact the same reason why number_format throws a warning on an invalid datatype because it cannot convert 1,99 to a float internally.
The following should work:
$float = "1,99";
echo "<p>$float<br>";
$val = number_format(str_replace(',', '.', $float), 2,'.', ',');
echo "$float</p>";
floatval recognizes the comma (,) as a character and not as a number, so it cuts off everything that comes after it. In this case, that's the 99. Please use a dot (.) instead of a comma (,) and it will probably work.
Example floatval (source: http://php.net/manual/en/function.floatval.php):
<?php
$var = '122.34343The';
$float_value_of_var = floatval($var);
echo $float_value_of_var; // 122.34343
?>
1,99 is not a valid php float. The issue is your comma (,). In PHP you have to use dot (.) as floating point separator.
<?php
$float = "1.99";
echo "<p>$float<br>";
$float = (float)$float;
$val = number_format($float, 2,'.', ',');
echo "$float</p>";
?>

How can I stop PHP from changing all my decimal separators?

My (MySQL) tables have columns with currency values set as Decimal(10,2) with decimals separated by commas. However whenever i query them, php turns all my commas into periods and invalidates my results. Can I stop it doing that? It affects both my SELECT and my INSERT/UPDATE.
When I select, for example, 123,00 php turns it into 12300.00; same for inserting a number: i insert 123,00 but the value in the table becomes 12300,00 again. Is there a way to make comma the default decimal separator?
have you looked in to
http://php.net/manual/en/function.money-format.php
$number = 1234.56;
// let's print the international format for the en_US locale
setlocale(LC_MONETARY, 'en_US');
echo money_format('%i', $number) . "\n";
For the PHP part this might me helpful
<?php
$number = 1234.56;
// english notation (default)
$english_format_number = number_format($number);
// 1,235
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56
$number = 1234.5678;
// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
?>
This should give you a clue on how to get the right output from your PHP code.
Don't care on how the database stores your numbers, neither on how PHP does it internally.
Use the number_format to get your desired output.
See also PHP: number-format for more on that.

php preg_match_all results from (numerical) STRING to DECIMAL - type

I have script that identifies with preg_match_all some numbers from a given file and in a given format '#(\d\,\d\d\d\d)#' (decimal, with 4 decimals). With them, later, I need to do some math operations to find out the sum, average etc.
With print_r I can see all matches from the array and it is ok (4,3456, 4,9098, etc.). I verify the type of variables and gettype() returned string
Unfortunately I cannot do math operations with them because when I use the variables in a math expression the result is always rounded regardless of what came afer the comma.
For example:
4,3456 + 4,9098 + 4,3456 = 12, or 12,0000 -- if I use number_format.
I used . instead of , in the numbers, I formatted the results with number_format, but have had no success. It seems I am missing something.
Thanks for help!
The error happens even before the number_format call -- PHP considers . as the decimal separator, not ,. you need to str_replace all your array elements:
$values_array = str_replace(",", ".", $values_array)
PHP uses the . character as decimal separator, so you have to replace the , by a . in your matched numbers before converting them to numbers:
$number = floatval(strtr("1,234", ",", "."));
// 1.234
Example:
<?php
$numbers = array("1,234", "5,67");
$numbers = str_replace(",", ".", $numbers);
echo number_format($numbers[0] + $numbers[1], 4, ',', ' ');
Try it here: http://codepad.org/LeeTiKPF

PHP and Money, converting money to cents

So I have done a fair bit of research on how to store "money" in a database and I think the system I want to use is
Converting Money into CENTS and then storing the CENTS in a MySQL DB with a field type of DECIMAL (19,4).
My question is, IF I have an input field from the user... how do I deal with multiple input types.
IE:
$input = "1,346.54"
$input = "10,985.23"
$input = "110,400.50"
$input = "1033.44"
etc etc...
What would be the best method for converting this to CENTS? As we have to deal with 'strings' and convert them to INT, and divide by 100... Everything that I try throws issues because of the "comma" separation with the numbers.
Any thoughts or direction would be greatly appreciated.
function getMoneyAsCents($value)
{
// strip out commas
$value = preg_replace("/\,/i","",$value);
// strip out all but numbers, dash, and dot
$value = preg_replace("/([^0-9\.\-])/i","",$value);
// make sure we are dealing with a proper number now, no +.4393 or 3...304 or 76.5895,94
if (!is_numeric($value))
{
return 0.00;
}
// convert to a float explicitly
$value = (float)$value;
return round($value,2)*100;
}
Looks like there is a NumberFormatter class which provides a parseCurrency method. Have a look at http://www.php.net/manual/en/numberformatter.parsecurrency.php
The example provided is
$fmt = new NumberFormatter( 'de_DE', NumberFormatter::CURRENCY );
$num = "1.234.567,89 $";
echo "We have ".$fmt->parseCurrency($num, $curr)." in $curr\n";
You can remove the commas like this:
$input = str_replace( ',', '', $input);
At this point, you can convert to cents by converting to a float and multiplying by 100. However, this is probably unnecessary. You would potential encounter precision issues when performing math operations, but simply storing the values in the database can be done in the original form without alteration of the value (assuming your DB tables are properly structured):
$input = (float)str_replace( ',', '', $input);
function convert_to_cents($v)
{
$v = str_replace(',','',$v);
$p = explode('.',$v);
if(strlen($p[1])<2){ $p[1] = $p[1]*10;}
return ($p[0]*100)+$p[1];
}
This converts most of the decimal currencies to their subunits.
$1,234,567.89 = 123456789
£ 1,234,567.89 = 123456789
€1.234.567,89 = 123456789
12,34 EUR = 1234
12,34 € = 1234
12,30 € = 1230
1,2 = 102
function convertDecimalCurrencyToSubUnit($str)
{
if( preg_match('/^(.+)[^\d](\d|\d\d)[^\d]*$/', $str, $m) )
return intval(preg_replace('/[^\d]/', '', $m[1]) . ( (strlen($m[2])>1) ? $m[2] : ('0' . $m[2]) ));
return 0;
}
Probably just remove the ',' and the '.' from the string, the result is the amount in cents.
You will probably need to parse the string from the back using strrpos ... If you find a comma 2 spots from the end, then its prob safe to assume its foreign currency and those are the CENTS... Once you determine that, use a regex to strip the remaining commas (after you convert the "CENTS" comma to a decimal of course) ... Now you have a normal DEC number to play with.
Use this to find the last comma in your string ... strrpos
Use this to replace the commas preg_replace
Here is a helpful regex website .. regexlib
//Finding the last comma
$yourCommaPos = strrpos($myString, ',');
if ($yourCommaPos == strlen($myString) - 2) {
//Comma is foreign currency decimal
// Replace with '.'
} else {
//Not foreign Currency so...
//Strip Commas
preg_replace(',', '', $myString);
}

Decimal number with comma instead of point (php and sql)

I'm doing a little application of adding prices and decimals. Points are normal to use with decimals, but how can I write decimal number with comma as input (543,35 instead of 543.35) and then maybe change it with point to the database (mysql)? Then print it back form the database with the comma. Reason is that comma (,) is more used in Finland than point (.) when write decimal numbers.
Thank you very much!
Samuel
$input = '5,50';
$output = str_replace(',', '.', $input);
var_dump($output); // string(4) "5.50"
$number = (float)$output;
var_dump($number); // float(5.5)
you need not do anything in the sql end. you want to format the decimal value in php (this assumes php4/php5): Set the third parameter $dec_point to ','
// string number_format ( float $number , int $decimals , string $dec_point , string $thousands_sep )
<?php
$number = 1234.56;
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56
$number = 1234.5678;
// english notation without thousands seperator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
?>
source:
http://php.net/manual/en/function.number-format.php
Cheers!
the PHP number_format function is what you need :
number_format(5.50, 2, ',');
...should do the trick.
As it's been said, it's best to save the value as a float and then format for display. As an alternative to the previously suggested number_format(), you could try money_format() http://us.php.net/manual/en/function.money-format.php It doesn't work in a windows environment though if that is important to you.
No, using comma as a decimal separator for arithmetic operations is not supported. Filter your input and replace the comma with a period, then format your output as you wish.

Categories