Fluinc
Fluinc

Reputation: 491

PHP Decimal128 string formating

I am using MongoDB to store values as Decimal128 and using PHP with Twig to display them. My question is there a format the output with a thousands separator? I have tried using number_format, but that doesn't work because the value is a string not a int or float. I don't want to type cast the value because I want the value to be precision.

Examples:

1000.382 = 1,000.382
99.01    = 99.01
1900000  = 1,900,000

I wrote a function to do this. Still wondering if there is a better way to do it.

<?php
$n = '12345.001';

echo fNumString($n);

function fNumString ($number_string) {
    $ex_num = explode('.', $number_string);
    $whole_num_len = strlen($ex_num[0]);

    $formated = '';
    if ($whole_num_len > 3) {
        for ($i = 0; $i < $whole_num_len; $i++) {
            $formated .= $ex_num[0][$i];

            if ((($whole_num_len - ($i + 1)) % 3) == 0 && $whole_num_len != ($i + 1))
                $formated .= ',';
        }
    } else
        $formated = $ex_num[0];


    if (count($ex_num) == 2)
        $formated .= '.' . $ex_num[1];

    return $formated;
}

Upvotes: 0

Views: 339

Answers (1)

Jeto
Jeto

Reputation: 14927

You could:

  • split the number string into integer and decimal parts using explode,
  • reverse the integer part using strrev,
  • add a thousands separator every 3 digits within that integer part using preg_replace,
  • reverse the integer part back using strrev,
  • return it concatenated with the decimal separator and the decimal part

Code:

function fNumString(string $numberString, string $decimalPoint = '.', string $thousandsSeparator = ','): string
{
  [$integerPart, $decimalPart] = array_pad(explode('.', $numberString, 2), 2, null);
  $integerPart = strrev(preg_replace('/\d{3}(?=\d)/', '\0' . $thousandsSeparator, strrev($integerPart)));

  return $integerPart . ($decimalPart ? $decimalPoint . $decimalPart : '');
}

Demo: https://3v4l.org/m3jUC

Note: you could leave out the last 2 parameters of number_format, I like keeping them out for clarity (and in case they change the default values later for some reason).

Upvotes: 1

Related Questions