Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Illuminate/Support/Number.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,19 @@ public static function percentage(int|float $number, int $precision = 0, ?int $m
* @param int|float $number
* @param string $in
* @param ?string $locale
* @param ?int $precision
* @return string|false
*/
public static function currency(int|float $number, string $in = 'USD', ?string $locale = null)
public static function currency(int|float $number, string $in = 'USD', ?string $locale = null, ?int $precision = null)
{
static::ensureIntlExtensionIsInstalled();

$formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::CURRENCY);

if (isset($precision)) {
$formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);
}

return $formatter->formatCurrency($number, $in);
}

Expand Down
12 changes: 12 additions & 0 deletions tests/Support/SupportNumberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ public function testToCurrency()
$this->assertSame('$5.32', Number::currency(5.325));
}

public function testToCurrencyWithPrecision()
{
$this->needsIntlExtension();

$this->assertSame('$0', Number::currency(0, precision: 0));
$this->assertSame('$2', Number::currency(1.50, precision: 0));

$this->assertSame('-$2', Number::currency(-1.75, precision: 0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dwightwatson Do we have a way to control the rounding mode her? As i don't think that silently rounding up to the nearest integer is what is actually wanted when dealing with money precision wise?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, so it looks like it does support a ROUNDING_MODE and then there are a heap of constants to control the direction. I'm not sure the nicest way to expose this in the helper without having to take in one of the constants. Do you have any ideas?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also worth considering that if there's reason enough to support controlling rounding it should probably also be added to Number::format() for consistency.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely like this PR, but I should mention that I think as soon as we start rounding currencies, we are entering dangerous territory. To be fair, just using floating point numbers for currency is also living on the edge in my opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While looking for inspiration on how to handle rounding I did note that number_to_currency in Rails also supports precision without control over the rounding direction.

$this->assertSame('$5', Number::currency(5.00, precision: 0));
$this->assertSame('$5', Number::currency(5.325, precision: 0));
}

public function testToCurrencyWithDifferentLocale()
{
$this->needsIntlExtension();
Expand Down