check to see if number ends in .00 using php - php

I'm working on something in zen cart and I don't want .00 to display on prices.
I thought I fixed the issue by doing
$price=number_format($special_price,2,'.','');
but zen cart has a function that adds the required currency symbol to the front or back of the number
$currencies->format($price)
The problem is that this function adds the .00 back onto the value!
The code for the function is
$format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(zen_round($number * $rate, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
If I duplicate that function so that I have $currencies->format2($price) and change it to
$format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(zen_round($number * $rate, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['0'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
then it will add the currency symbol without adding the decimal places back in. Of course, when you have a price such as 49.50 it is then rounding this up to 50
I did try
$cur_price=$currencies->format($special_price);
$price=str_replace(".00", "", (string)number_format ($cur_price, 2, ".", ""));
The thinking behind it being that I could apply the currencies symbol first and then remove the decimals if they were .00, but that resulted in a blank space where the price should be.
I either need to find a way to check if
$price
ends in .00 so i can conditionally call $currencies->format() or $currencies->format2(), or I need to modify the original function to not put the decimal in place if it's .00, but allow it at all other times.

Would
$price = substr($price, -3) == ".00" ? substr($price, 0, -3) : $price;
work?

You can use PHP's explode() function to split the price into two parts (the part before and after the decimal), then check to see if it's what you want.
Try running the code below, then run it again after changing the $curr_price to something ending in 00.
<?php
$curr_price = '45.99';
$price_array = explode('.', $curr_price);
if ($price_array[1] == '00')
{
$curr_price = $price_array[0];
}
echo 'The price is ' . $curr_price . "<br>";
?>

Related

How to correctly do maths with higher numbers in PHP

I am trying to display the total amount which is product price times quantity.
This works perfectly for numbers under 1000, but above that a dot is added and my script breaks. How can I fix that?
I have these numbers:
150,00
1.200,00
They are looped with variable $price.
I then replace all commas for dots like this:
$subtotalreken = str_replace(',','.',$price);
$subtotalreken then contains:
150.00
1.200.00
I then multiply this with the quantity amount like this:
$totalfinal = $subtotalreken * $cart['quantity'];
The quantity is 2 for both products, and if I echo $totalfinal, this is my result:
300
2.4
Why is it 2.4? And not 2.400?
I need the european/dutch format, so dots for every three numbers and cents after the comma. How can I do that?
Assuming that the "number" uses comma as decimal and dots as thousands separator: remove all dots and replace the comma with dot so that 1.234,56 becomes 1234.56:
$value = (float) strtr("1.234,56", ["." => "", "," => "."]); // 1234.56
You can format the value again using number_format:
echo number_format($value, 2, ",", "."); // 1.234,56
Before calculations remove any formatting from your number (just make sure you always have 2 decimal places number):
$number = preg_replace('/[^\d]/', '', $input);
Then do your calculations (number is in cents) and show to user formatted number:
echo number_format($number * $qunatity / 100, '.', ',', 2);

Format number as currency

I am (learning) using PHP to select column data from MySQL into an array using this, CONCAT('$',FORMAT(price, '5')) as price and it outputs $1,751.60000 or $10.00230 or $7.23000 which is great.
However, I would like to remove the trailing zeros but still be able to have a minimum of two decimal places
$1,751.60000 = $1,751.60
$10.00230 = $10.0023
$7.23000 = $7.23
I have read a number of similar post regarding number to currency conversion but none doesn't seem to solve my problem as they remove all the trailing zeros.
We will implement this in two way.(Mysql, PHP).
MYSQL:
FORMAT('price', 2 ) This is mysql function. It takes first parameter as value & second parameter is the number of decimal places.
Syntax:
FORMAT( value, Decimal );
Example:
FORMAT('1751.60000', 2 ) => 1751.60 // Output
FORMAT('1751.60000', 3 ) => 1751.600 // Output
PHP:
In PHP we have number_format() function. This is working same as MYSQL.
Syntax:
number_format( value, Decimal );
Example:
number_format('1751.60000', 2 ) => 1751.60 // Output
number_format('1751.60000', 3 ) => 1751.600 // Output
The Best way is to implement at MYSQL.
Note: These both function round up the values.
I will post this code in PHP since it is easier for me.
$price = $row['price']; // the original price
if (number_format($price, 2) == $price) {
echo '$'.number_format($price, 2);
} else {
echo '$'.rtrim(number_format($price, 5),'0');
}
rtrim will remove any trailing character specified. In this case, remove trailing zeros.
Note : I only put this code number_format($price, 5) because of the sample of the question. If you wish to keep all decimal number minus trailing zeros, just using $price is enough.

How to delete trailing zeros after the 3rd decimal place in PHP?

thanks in advance.
I have a WP WooCommerce store and need to upload some prices that have 3 decimal places, e.g. £0.012 (products that are purchased in volumes of 000s).
The majority of my products are 'ordinary' with 2 decimal places.
There is a function in WooCommerce that allows for 3 decimal places - fine. Also a function to delete trailing zeros, but it deletes them if it's an integer e.g. £10.00 becomes £10.
My problem arises when the 95% of 'ordinary' price products start showing £10.000 or £5.230.
In a nutshell I'm looking for a way to delete trailing zeros but ONLY after the 3 decimal place;
Retain - £0.012
Delete any 3rd decimal 0 on prices like £10.00 or £5.23
Does anyone have a good solution?
Thanks
If you want to use regular expressions you can match them with
(?<=\d{2})(0+)$
preg_replace("/(?<=\d{2})(0+)$/", "", $price_string)
to match all zeroes which come after at least two digits. (It will match the zeroes in parenthesis):
12.002(0)
12.00(0000)
12.01(000000)
12.232(0)
12.123
an if else statement would probably work, unless you also have prices like 10.001:
$price = '0.001';
if ($price < 1) {
// don't round
} else {
$price = number_format($price, 2);
}
or just
$price = ( $price < 1 ) ? $price : number_format($price, 2) ;
Why not just something like this ↓ ?
$numberAsString = number_format($yourUglyNumber, 2, '.', ' ');
PHP function number_format
If you get the number as string with the money sign, you can first filter this out:
$moneyString = "£300.4578525";
// remove all non-numeric and cast to number
$moneyNum = preg_replace("/[^0-9.]/", "", $moneyString) + 0;
// format
$formatted = number_format($moneyNum, 2, '.', ' ');
// add the money symbol if you want
$formatted = '£' + $formatted.

How do I amend an existing javascript to display currency values including cents?

A site I'm working on (which I inherited...I don't know javascript that well) has code currently set up to display ".00" at the end of any number in the database (a PHP include page, actually) such that it displays as currency on an online form.
My client now wants to add an amount to the list which includes cents ($5.50), and I need help modifying or amending the script so I can include these non-whole currency amounts.
Here is the snippet of the script that (I think/presume) addresses the currency formatting:
function CurrencyFormatted(amount)
{
var i = parseFloat(amount);
if(isNaN(i)) { i = 0.00; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if(s.indexOf('.') < 0) { s += '.00'; }
if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
s = minus + s;
return s;
}
Is there a way to add to or change this code so that I can display the specific cents needed for this one (and future similar) amounts?
That code is doing some interesting rounding things, which I can't really address, but to format a number with a fixed number of digits to the right of the decimal, use the toFixed function on numbers:
var n = 1.2345;
n.toFixed(2); // "1.23"
Note that it does rounding, so:
(1.234).toFixed(2); // "1.23"
(1.235).toFixed(2); // "1.24"
(You don't need the parens when you're calling toFixed on a variable, but you do need them when calling it on a literal as I did in the two examples above. Naturally, in your case, you'll be using a variable so no need for them.)
Re your comment/question below:
Thanks for the quick replies! I guess I should have said I don't know javascript AT ALL, so my questions are: 1) where do I insert the codes you offer above into my existing code...
1) The code you quoted in your question is doing a bunch of operations on the number fed into it, including adding half a cent to it before trying to round it to two digits (in a very non-optimal way). If the goal now is to faithfully reproduce a rounded-to-two-digits version of the number fed in (none of this adding half-a-cent stuff), you can replace the entire function with this:
function CurrencyFormatted(amount)
{
return parseFloat(amount).toFixed(2);
}
If you want to continue adding half a cent to it:
function CurrencyFormatted(amount)
{
return (parseFloat(amount) + 0.005).toFixed(2);
}
...and 2) will this allow all of my existing other numbers to continue displaying as they are (e.g. "25" in my include file displays as "25.00")?
Any number (or numeric string) you feed into the above will be formatted with two digits to the right of the decimal, even if those digits are 00. So with the above, CurrencyFormatted("25") will return "25.00".
...Or do I use this code you suggest to replace part or all of the sample code I posted, and thus, would I then need to change all my database numbers to accommodate this? (i.e. should I add two zeros to the end of all my whole numbers now? (25 becomes 2500, etc.)
You don't need to add .00 to whole numbers in the database or anything like that.
If you wanted todo this with PHP checkout money_format() heres an example:
<?php
$value = 5;
setlocale(LC_MONETARY, 'en_US');
echo '$'.money_format('%i', $value) . "\n";//$5.00
$value = 5.545;
setlocale(LC_MONETARY, 'en_US');
echo '$'.money_format('%i', $value) . "\n";//$5.54
$value = 9.99;
setlocale(LC_MONETARY, 'en_US');
echo '$'.money_format('%i', $value) . "\n";//$9.99
?>

Calculating total price from string value in php

I have a e-commerce shop and on the shopping cart page it gives me a separate price for every product, but I need total price.
in order to do that, I need to calculate all these values together and that's fine.
But, what bugs me is that I should calculate the sum of variables that are given in this format:
$455.00
What is the best way to extract the value "455" so I could add it to another value afterwards?
I hope I made myself clear...
Don't use float, but instead use an integer in cent. Floats are not precise (see Floating Point Precision), so the calculation tend to fail if you use floats. That's especially a burden if it is related to payments.
$str = '$455.00';
$r = sscanf($str, '$%d.%d', $dollar, $cent);
if ($r <> 2 or $cent > 99 or $cent < 0 or $dollar > 9999 or $dollar < 0) throw new Exception(sprintf('Invalid string "%s"', $str));
$amountInDollarCents = $dollar * 100 + $cent;
echo $str, ' -> ', $amountInDollarCents;
Demo
If you need only the dollar sign removed, use str_replace. To convert that to int or float, typecast it. However, using float results in non-exact calculations so be careful with it!
$newval = (int)str_replace('$', '', '$455.00');
I think that your ECommerce site only has $ (USD)
$price= substr($string_price,1);
This will convert your string to a float:
$price = (float)substr("$455.00", 1);
echo($price);
For more information, you can see this answer, which has a couple of good links for you in it.
What about the following:
$amount = array();
$amount[0] = '$455.15';
$amount[2] = '$85.75';
$total = 0;
foreach ($amount AS $value) {
$value = str_replace('$', '', $value);
$total += $value;
}
echo $total . "\n";
The cleaning operation is:
$value = str_replace('$', '', $value);
You might want to extract it in a function, especially if you need to use it in more than one place.
Another thing to think about is, why do you have the value in such way? It's a display format and such conversion should be the last to be done, ideally by the template. Maybe, if possible, you should consider to fix the code before, instead of applying a patch like this one.
It really looks like your program is doing it wrong. You should really represent all prices as (double) instead of a string. Then only when you need to show the price to the user you would prepend the $ sign to it, converting it to a string. But your program should really treat prices as numbers and not strings.
If you storing your price in the database as a string "$5.99" then you are really doing it wrong.
It's been a long time since I worked with PHP, so I don't know what the best practice would be for working with currency. One quick method would be to remove "$" and ".", and just add together the resulting as integers.
use str_replace() for instance, and replace "$" and "." with an empty string: http://se2.php.net/manual/en/function.str-replace.php
This will give you the whole sum in cents (thus avoiding some potential rounding problems). You can then divide it by 100 and format it however you like to display the sum as dollars.

Categories