Search code examples
phplaravelnumber-formatting

Conditional currency decimals formatting with NumberFormatter


Is there a way to format currency conditionally depending on number of decimals? For example :

CHF 1'200.00 becomes CHF 1'200.-

CHF 1'200.2 becomes CHF 1'200.20

CHF 1'200.20 becomes CHF 1'200.20

MIN_FRACTION_DIGITS attribute will set it all to .00, which solves 2nd and 3rd case, but will not solve the first one.

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

Is there a way to do that? Or at least format decimals as subscript, for example?


Solution

  • The only way I see is to set the settings for the NumberFormatter based on a condition and then adding .- if the result is a whole number.

    // 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 .= '.-';
    }
    

    This should cover the cases in your question:

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