PHP将数字格式化为区域设置并返回

时间:2017-04-02 15:08:39

标签: php internationalization locale number-formatting

经过大量研究后,我实际上使用以下函数将数字格式化为用户设置的语言环境:

function number_format_i18n($number, $decimals=0) {
    $locale = localeconv();
    return number_format($number,$decimals, $locale['decimal_point'], $locale['thousands_sep']);
}

我将使用它来格式化DB中的数字。

但是如果我有一个用户可以输入数字的表单,我需要一个函数来格式化它,这样我就可以保存到数据库中。在这里,我找到了这个解决方案:

function number_format_en($number) {
    // $_SESSION['lang']['locale'] has the locale like de_DE, ar_AE, tr_TR, ...
    $fmt = numfmt_create($_SESSION['lang']['locale'], NumberFormatter::DECIMAL);
    return numfmt_parse($fmt, $number);
}

这适用于我测试的大多数语言环境,但不适合所有人!举个例子:如果我使用阿拉伯语(ar_AE):

$randomNumber = 3171003633.95;
$number2locale = number_format_i18n($randomNumber, 2);
// works as expected: 3,171,003,633.95
// now format it back:
$locale2number = number_format_en($number2locale);
// here I get this: 3.171

如何以安全的方式“返回”格式化格式化区域设置输入的数字?或者有没有办法检测任何类型的数字格式并将其格式化为格式化,以便将其保存在数据库中?

1 个答案:

答案 0 :(得分:0)

所以,不知道这是否是一个好的解决方案 - 但似乎工作正常:

function number_format_en($number) {
    // first remove everything execpt -,.
    $cleanNumber = preg_replace('/[^\\d-,.]+/', '', $number);

    $last_dot = strrpos($cleanNumber, '.');
    $last_comma = strrpos($cleanNumber, ',');

    if($last_dot !== false || $last_comma !== false) {
        if($last_dot > $last_comma) { // decimal seperator = dot
            $decimal_point = '.';
            if(substr_count($cleanNumber, '.') > 1) {
                // could be totaly wrong 1,234.567.890
                // or there are no decimals 1.234.567.890
                // removing all dots and commas and returning the value
                return preg_replace('/[^\\d-]+/', '', $cleanNumber);
            }
        } else { // decimal seperator = comma
            $decimal_point = ',';
            if(substr_count($cleanNumber, ',') > 1) {
                // could be totaly wrong 1.234,567,890
                // or there are no decimals 1,234,567,890
                // removing all dots and commas and returning the value
                return preg_replace('/[^\\d-]+/', '', $cleanNumber);
            }
        }
    } else { // no decimals
        $decimal_point = false;
        $decimals = 0;
    }

    if($decimal_point !== false) {
        // if decimals are delivered, get the count of them
        $length = strlen($cleanNumber);
        $position = strpos($cleanNumber, $decimal_point);
        $decimals = $length - $position - 1;

        if($decimal_point == '.') {
            // remove all commas if seperator = .
            $cleanNumber = str_replace(',', '', $cleanNumber);
        } elseif($decimal_point == ',') {
            // remove all dots if seperator = ,
            $cleanNumber = str_replace('.', '', $cleanNumber);
            // now switch comma with dot
            $cleanNumber = str_replace(',', '.', $cleanNumber);
        }
    }
    return $cleanNumber;
}

我将检查最后一个点或逗号,并根据我格式化数字,函数返回与原始数字相同的小数位数。有一个“已知”错误:如果有人输入完整的数字,如1.000.000或1,000,000,则返回1000000。

举个例子:

number_format_en('1.234.567,89') // 1234567.89
number_format_en('-1,234,567.89') // -1234567.89
number_format_en('1.234.567.89') // 123456789 (only dots)
number_format_en('1,234,567,89') // 123456789 (only commas)

如果有人可以发表评论,如果这是一个好方法或者是一个更好的解决方案的答案,那将会很好:)