Domanda

I have ended up with a little bit of an overkill here, but I just cannot seem how to nail it:

$formatter = new NumberFormatter('lv_LV', NumberFormatter::DECIMAL);

$formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);
$formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 2);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 2);
$formatter->setAttribute(NumberFormatter::DECIMAL_ALWAYS_SHOWN, 2);

What I am trying to achieve here is:

+-------+--------+----------+-------+
| INPUT | ACTUAL | EXPECTED | VALID |
+-------+--------+----------+-------+
|  5,77 |   5.77 |     5.77 | YES   |
|  5,20 |    5.2 |     5.20 | NO    |
|  5,00 |      5 |     5.00 | NO    |
|     0 |      0 |     0.00 | NO    |
+-------+--------+----------+-------+

In short, I always want 2 digits behind the floating point.

How do I achieve this with PHP's NumberFormatter?

È stato utile?

Soluzione 2

You should use http://php.net/manual/en/function.number-format.php

$var = number_format(553,2);
echo $var

Where 553 is the number and 2 is the amount of decimal places to display. It will ouput

553,00

NumberFormatter has a way of dealing with currencies if this is what you are after http://php.net/manual/en/function.money-format.php

Altri suggerimenti

The accepted answer is correct, I am looking to provide clarification as to why the OP was not receiving the expected results with NumberFormatter.

NumberFormatter::parse will output a float and accepts a string argument in the specified locale format. Parse however does not format the output. It is the equivalent of performing echo (float) '5.20'; //(float) 5.2

NumberFormatter::format will output a string in the specified locale format and accepts an integer or float argument. It is the equivalent of performing echo number_format(5.2, 2); //(string) "5.20" However number_format uses default values as the fraction and thousands separators and they would need to be changed based on desired display rules.

NumberFormatter requires that you call the parse method prior to calling the format method, for it to convert the locale specific string value to the integer or float value equivalent and have a separate NumberFormatter for your desired output.

Example https://3v4l.org/HRnQN

$lv = new \NumberFormatter('lv', \NumberFormatter::DECIMAL);
$lv->setAttribute($input::FRACTION_DIGITS, 2); //applies rounding during format

$en = new \NumberFormatter('en', \NumberFormatter::DECIMAL);
$en->setAttribute($output::FRACTION_DIGITS, 2); //applies rounding during format

foreach (['5,77', '5,20', '5,2', '5,00', '5', '0'] as $value) {
   $parsed = $lv->parse($value);
   var_dump($parsed); //convert locale string to float value
   var_dump($en->format($parsed)); //convert float to locale string
   var_dump($lv->format($parsed)); //convert float to locale string
   echo "<br/>\n";
}

$lv::parse($value)

+-------+--------+----------+-------+
| Value |  Parse | EXPECTED | VALID |
+-------+--------+----------+-------+
|  5,77 |   5.77 |     5.77 | YES   |
|  5,20 |    5.2 |      5.2 | YES   |
|   5,2 |    5.2 |      5.2 | YES   |
|  5,00 |      5 |        5 | YES   |
|     5 |      5 |        5 | YES   |
|     0 |      0 |        0 | YES   |
+-------+--------+----------+-------+

$en::format($parsed)

+-------+--------+----------+-------+
| Value | Format | EXPECTED | VALID |
+-------+--------+----------+-------+
|  5,77 |   5.77 |     5.77 | YES   |
|  5,20 |   5.20 |     5.20 | YES   |
|   5,2 |   5.20 |     5.20 | YES   |
|  5,00 |   5.00 |     5.00 | YES   |
|     5 |   5.00 |     5.00 | YES   |
|     0 |   0.00 |     0.00 | YES   |
+-------+--------+----------+-------+

$lv::format($parsed)

+-------+--------+----------+-------+
| Value | Format | EXPECTED | VALID |
+-------+--------+----------+-------+
|  5,77 |   5,77 |     5,77 | YES   |
|  5,20 |   5,20 |     5,20 | YES   |
|   5,2 |   5,20 |     5,20 | YES   |
|  5,00 |   5,00 |     5,00 | YES   |
|     5 |   5,00 |     5,00 | YES   |
|     0 |   0,00 |     0,00 | YES   |
+-------+--------+----------+-------+
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top