php 使用NumberFormatter设置条件货币小数格式

blmhpbnm  于 2023-04-28  发布在  PHP
关注(0)|答案(2)|浏览(129)

有没有一种方法可以根据小数位数有条件地格式化货币?例如:

1200瑞士法郎。00变为1 '200瑞士法郎。-
1200瑞士法郎。2变为1 '200瑞士法郎。20
1200瑞士法郎。20变为1 '200瑞士法郎。20

MIN_FRACTION_DIGITS属性将全部设置为。00,这解决了第二和第三种情况,但不会解决第一种情况。

$formatter->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 2);

有办法做到吗?或者至少将小数格式为下标,例如?

n6lpvg4x

n6lpvg4x1#

我看到的唯一方法是根据条件设置NumberFormatter的设置,然后如果结果是整数,则添加.-

// Check if we have a decimal that isn't .00 and adjust settings accordingly.
if (round($value, 2) == round($value, 0)) {
    $formatter->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 0);
} else {
    $formatter->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 2);
}

// Format the number
$formattedValue = $formatter->formatCurrency($value, 'CHF');

// Add '.-' if we have a whole number.
if (strpos($formattedValue, '.') === false) {
    $formattedValue .= '.-';
}

这应该涵盖您问题中的情况:

  • 1200.00 -〉CHF 1'200.-
  • 1200 -〉CHF 1'200.-
  • 1200.20 -〉CHF 1'200.20
  • 1200.2 -〉CHF 1'200.20
yvfmudvl

yvfmudvl2#

您可以使用正则表达式替换一个严格格式的值,其中始终包含小数,以替换具有自定义结尾的零填充值,并将与具有不同货币分隔符的各种区域设置一起使用。

function customCurrencyFormat(
    \NumberFormatter $formatter,
    string $currency,
    string|int|float $value
): string {
    // Ensure there are at least and no more than 2 fractional digits
    $formatter->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 2);
    $formatter->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 2);
    // Get the locale's monetary separator (usually , or .)
    $monetarySep = $formatter->getSymbol(
        \NumberFormatter::MONETARY_SEPARATOR_SYMBOL
    );
    // Replace zero padded endings (like .00) with the separator symbol followed
    // by a dash.
    $formattedValue = preg_replace(
        '/' . preg_quote($monetarySep) . '0+(?=([^0-9]+$|$))/',
        $monetarySep . '-',
        $formatter->formatCurrency($value, $currency)
    );
    return $formattedValue;
}

customCurrencyFormat($formatter, 'CHF', '634598'); // CHF 634’598.-
customCurrencyFormat($formatter, 'CHF', '3254636.4'); // CHF 3’254’636.40

即使您切换到具有不同分隔符和货币的其他区域设置,此功能也将起作用。请注意,这可能会让一些人感到困惑,因为它看起来像一个负值。
另外请注意,如果您使用的PHP版本早于8。0,您可能需要将函数最后一个$value参数的类型提示替换为mixed,因为早期版本不支持联合类型。

相关问题