[PHP] Read SI formatted numbers as floats

Simple function to convert numbers from SI notation to float:
– decimal point separator – dot or comma
– thousands separator – space

In this case used to load money value from strings in different formats.

Examples:
##
# ###
# ###, #
# ###.#
#,###
12 -> 12
1 234 -> 1234
1 234,5 -> 1234.5
1 234.5 -> 1234.5
1,234 -> 1.234

<?php
$validTests = [
    '1 234',
    '-1 234',
    '- 1 234',
    '1 234.00',
    '-1 234.00',
    '1 234,00',
    '-1 234,00',
    '1234',
    '-1234',
    '1234.00',
    '-1234.00',
    '1234,00',
    '-1234,00',
    '1 234,00000000000',
    '1234,00000000000',
    '1 234,34545654565',
    '-1 234,34545654565',
    '1234,34545654565',
    '-1234,34545654565',
    '1 234 567',
    '1 234 567.00343',
    '1 234 567,34565',
    '1.234',
];

$invalidTests = [
    '-1 $',
    '1,234.00',
    '1.234,00',
    '-1.234,00',
    '-1.234.567',
    '-1.234.567,00',
    '-1,234,567.00',
];

function getAmountValue($money)
{
    $value = trim($money);
    $value = str_replace(' ', '', $value);

    $invalidCharacters = preg_replace('/([0-9\.,-])/i', '', $value);
    if (!empty($invalidCharacters)) {
        throw new InvalidArgumentException('Money value string "' . $value . '" contains invalid characters: "' . $invalidCharacters . '"!');
    }

    $separatorsCount = mb_substr_count($value, '.') + mb_substr_count($value, ',');
    if ($separatorsCount > 1) {
        throw new InvalidArgumentException('Money value string "' . $value . '" contains more than 1 separator!');
    }
    $value = str_replace(',', '.', $value);

    return (float)$value;
}

foreach ($validTests as $money) {
    try {
        $value = getAmountValue($money);
    } catch (Exception $exception) {
        $value = $exception->getMessage();
    }
    echo var_export($money, true) . ' = ' . var_export($value, true) . PHP_EOL;
}

echo '--- INVALID ---' . PHP_EOL;

foreach ($invalidTests as $money) {
    try {
        $value = getAmountValue($money);
    } catch (Exception $exception) {
        $value = $exception->getMessage();
    }
    echo var_export($money, true) . ' = ' . var_export($value, true) . PHP_EOL;
}

Leave a Reply

Your email address will not be published. Required fields are marked *