8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如何将数字格式化为货币字符串

Vardan Grigoryants 1月前

61 0

我想用 JavaScript 格式化价格。我想要一个以浮点数作为参数并返回格式如下的字符串的函数:\'$ 2,500.00\'我该怎么做?

我想用 JavaScript 格式化价格。我想要一个以 为 float 参数并返回 string 格式如下的函数:

"$ 2,500.00"

我怎样才能做到这一点?

帖子版权声明 1、本帖标题:如何将数字格式化为货币字符串
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Vardan Grigoryants在本站《jquery》版块原创发布, 转载请注明出处!
最新回复 (0)
  • console.log(parseFloat('4.835').toFixed(2)); > 4.83 console.log(parseFloat('54.835').toFixed(2)); > 54.84 console.log(parseFloat('454.835').toFixed(2)); > 454.83 console.log(parseFloat('8454.835').toFixed(2)); > 8454.83 所有这些值的小数都应该是 .84 而不是 .83

  • 从您的方法 2 改进。从 var a = this.toFixed(precision).split('.'), 更改为 var multiplier = Math.pow( 10, precision + 1 ), wholeNumber = Math.floor( this * multiplier ); var a = Math.round( wholeNumber / 10 ) * 10 / multiplier; if (String(a).indexOf('.') < 1) { a += '.00'; } a = String(a).split('.'), 不要使用 toFixed 因为它有缺陷。

  • LPMR 1月前 0 只看Ta
    引用 4

    这里有一些解决方案,全部通过了测试套件。测试套件和基准测试都包含在内。如果您想复制粘贴进行测试,请尝试 此要点 .

    方法 0 (正则表达式)

    它基于 VisioN 的答案 ,但如果没有小数点,它就会修复。

    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('.');
            a[0] = a[0].replace(/\d(?=(\d{3})+$)/g, '$&,');
            return a.join('.');
        }
    }
    

    方法 1

    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('.'),
                // Skip the '-' sign
                head = Number(this < 0);
    
            // Skip the digits that's before the first thousands separator
            head += (a[0].length - head) % 3 || 3;
    
            a[0] = a[0].slice(0, head) + a[0].slice(head).replace(/\d{3}/g, ',$&');
            return a.join('.');
        };
    }
    

    方法 2(拆分为数组)

    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('.');
    
            a[0] = a[0]
                .split('').reverse().join('')
                .replace(/\d{3}(?=\d)/g, '$&,')
                .split('').reverse().join('');
    
            return a.join('.');
        };
    }
    

    方法 3(循环)

    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('');
            a.push('.');
    
            var i = a.indexOf('.') - 3;
            while (i > 0 && a[i-1] !== '-') {
                a.splice(i, 0, ',');
                i -= 3;
            }
    
            a.pop();
            return a.join('');
        };
    }
    

    使用示例

    console.log('======== Demo ========')
    console.log(
        (1234567).format(0),
        (1234.56).format(2),
        (-1234.56).format(0)
    );
    var n = 0;
    for (var i=1; i<20; i++) {
        n = (n * 10) + (i % 10)/100;
        console.log(n.format(2), (-n).format(2));
    }
    

    分隔符

    如果我们想要自定义千位分隔符或小数分隔符,请使用 replace()

    123456.78.format(2).replace(',', ' ').replace('.', ' ');
    

    测试套件

    function assertEqual(a, b) {
        if (a !== b) {
            throw a + ' !== ' + b;
        }
    }
    
    function test(format_function) {
        console.log(format_function);
        assertEqual('NaN', format_function.call(NaN, 0))
        assertEqual('Infinity', format_function.call(Infinity, 0))
        assertEqual('-Infinity', format_function.call(-Infinity, 0))
    
        assertEqual('0', format_function.call(0, 0))
        assertEqual('0.00', format_function.call(0, 2))
        assertEqual('1', format_function.call(1, 0))
        assertEqual('-1', format_function.call(-1, 0))
    
        // Decimal padding
        assertEqual('1.00', format_function.call(1, 2))
        assertEqual('-1.00', format_function.call(-1, 2))
    
        // Decimal rounding
        assertEqual('0.12', format_function.call(0.123456, 2))
        assertEqual('0.1235', format_function.call(0.123456, 4))
        assertEqual('-0.12', format_function.call(-0.123456, 2))
        assertEqual('-0.1235', format_function.call(-0.123456, 4))
    
        // Thousands separator
        assertEqual('1,234', format_function.call(1234.123456, 0))
        assertEqual('12,345', format_function.call(12345.123456, 0))
        assertEqual('123,456', format_function.call(123456.123456, 0))
        assertEqual('1,234,567', format_function.call(1234567.123456, 0))
        assertEqual('12,345,678', format_function.call(12345678.123456, 0))
        assertEqual('123,456,789', format_function.call(123456789.123456, 0))
        assertEqual('-1,234', format_function.call(-1234.123456, 0))
        assertEqual('-12,345', format_function.call(-12345.123456, 0))
        assertEqual('-123,456', format_function.call(-123456.123456, 0))
        assertEqual('-1,234,567', format_function.call(-1234567.123456, 0))
        assertEqual('-12,345,678', format_function.call(-12345678.123456, 0))
        assertEqual('-123,456,789', format_function.call(-123456789.123456, 0))
    
        // Thousands separator and decimal
        assertEqual('1,234.12', format_function.call(1234.123456, 2))
        assertEqual('12,345.12', format_function.call(12345.123456, 2))
        assertEqual('123,456.12', format_function.call(123456.123456, 2))
        assertEqual('1,234,567.12', format_function.call(1234567.123456, 2))
        assertEqual('12,345,678.12', format_function.call(12345678.123456, 2))
        assertEqual('123,456,789.12', format_function.call(123456789.123456, 2))
        assertEqual('-1,234.12', format_function.call(-1234.123456, 2))
        assertEqual('-12,345.12', format_function.call(-12345.123456, 2))
        assertEqual('-123,456.12', format_function.call(-123456.123456, 2))
        assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2))
        assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2))
        assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2))
    }
    
    console.log('======== Testing ========');
    test(Number.prototype.format);
    test(Number.prototype.format1);
    test(Number.prototype.format2);
    test(Number.prototype.format3);
    

    基准

    function benchmark(f) {
        var start = new Date().getTime();
        f();
        return new Date().getTime() - start;
    }
    
    function benchmark_format(f) {
        console.log(f);
        time = benchmark(function () {
            for (var i = 0; i < 100000; i++) {
                f.call(123456789, 0);
                f.call(123456789, 2);
            }
        });
        console.log(time.format(0) + 'ms');
    }
    
    // If not using async, the browser will stop responding while running.
    // This will create a new thread to benchmark
    async = [];
    function next() {
        setTimeout(function () {
            f = async.shift();
            f && f();
            next();
        }, 10);
    }
    
    console.log('======== Benchmark ========');
    async.push(function () { benchmark_format(Number.prototype.format); });
    next();
    
  • 有必要进行解释。例如,它怎么会如此简单,并且没有被过去 9 年(当时)的 50 多个答案所涵盖?

  • Number(value)
            .toFixed(2)
            .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
  • 这可能有点晚了,但这是我刚刚为同事想出的方法,用于 .toCurrencyString() 为所有数字添加区域感知函数。内部化仅用于数字分组, 而不是 货币符号 - 如果您要输出美元,请 "$" 按原样使用,因为 $123 4567 日本或中国的美元数量与 $1,234,567 美国的美元数量相同。如果您要输出欧元等,则将货币符号从 "$" .

    在 HTML 中的任意位置声明部分或任何必要的地方,就在你需要使用它之前:

      Number.prototype.toCurrencyString = function(prefix, suffix) {
        if (typeof prefix === 'undefined') { prefix = '$'; }
        if (typeof suffix === 'undefined') { suffix = ''; }
        var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/\./, '\\.') + "$");
        return prefix + (~~this).toLocaleString().replace(_localeBug, '') + (this % 1).toFixed(2).toLocaleString().replace(/^[+-]?0+/,'') + suffix;
      }
    

    然后你就完成了! (number).toCurrencyString() 在任何需要输出货币数字的地方使用。

    var MyNumber = 123456789.125;
    alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
    MyNumber = -123.567;
    alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
    
  • 通常,有多种方法可以做同一件事,但我会避免使用, Number.prototype.toLocaleString 因为它可以根据用户设置返回不同的值。

    我也不建议扩展 Number.prototype - 扩展本机对象原型是一种不好的做法,因为它可能导致与其他人的代码(例如库/框架/插件)发生冲突,并且可能与未来的 JavaScript 实现/版本不兼容。

    我相信正则表达式是解决这个问题的最佳方法,这是我的实现:

    /**
     * Converts number into currency format
     * @param {number} number    Number that should be converted.
     * @param {string} [decimalSeparator]    Decimal separator, defaults to '.'.
     * @param {string} [thousandsSeparator]    Thousands separator, defaults to ','.
     * @param {int} [nDecimalDigits]    Number of decimal digits, defaults to `2`.
     * @return {string} Formatted string (e.g. numberToCurrency(12345.67) returns '12,345.67')
     */
    function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){
        //default values
        decimalSeparator = decimalSeparator || '.';
        thousandsSeparator = thousandsSeparator || ',';
        nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits;
    
        var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits
            parts = new RegExp('^(-?\\d{1,3})((?:\\d{3})+)(\\.(\\d{'+ nDecimalDigits +'}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4]
    
        if(parts){ //number >= 1000 || number <= -1000
            return parts[1] + parts[2].replace(/\d{3}/g, thousandsSeparator + '$&') + (parts[4] ? decimalSeparator + parts[4] : '');
        }else{
            return fixed.replace('.', decimalSeparator);
        }
    }
    
  • 中的 NumberFormat 类 Google Visualization API .

    你可以做这样的事情:

    var formatter = new google.visualization.NumberFormat({
        prefix: '$',
        pattern: '#,###,###.##'
    });
    
    formatter.formatValue(1000000); // $ 1,000,000
    
  • 引用 10
    function CurrencyFormatted(amount)
    {
        var i = parseFloat(amount);
        if(isNaN(i)) { i = 0.00; }
        var minus = '';
        if(i < 0) { minus = '-'; }
        i = Math.abs(i);
        i = parseInt((i + .005) * 100);
        i = i / 100;
        s = new String(i);
        if(s.indexOf('.') < 0) { s += '.00'; }
        if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
        s = minus + s;
        return s;
    }
    

    来自 WillMaster .

  • 引用 11

    Patrick Desjardins 的答案看起来不错,但我更喜欢简单的 JavaScript 代码。下面是我刚刚编写的一个函数,用于接收数字并以货币格式(减去美元符号)返回:

    // Format numbers to two decimals with commas
    function formatDollar(num) {
        var p = num.toFixed(2).split(".");
        var chars = p[0].split("").reverse();
        var newstr = '';
        var count = 0;
        for (x in chars) {
            count++;
            if(count%3 == 1 && count != 1) {
                newstr = chars[x] + ',' + newstr;
            } else {
                newstr = chars[x] + newstr;
            }
        }
        return newstr + "." + p[1];
    }
    
  • toFixed() 是 Number 对象的一个​​函数,如果 var num 是字符串,它将无法对其起作用,因此附加上下文对我有帮助。

  • JavaScript 中 有一个内置函数 toFixed

    var num = new Number(349);
    document.write("$" + num.toFixed(2));
    
  • 这只是唯一正确的函数: > number_format(2030, 0, '.', ' ') < '2 030' 太棒了!谢谢

  • PHP 函数“number_format”有一个 JavaScript 端口。

    我发现它非常有用,因为它易于使用且 PHP 开发人员可识别。

    function number_format (number, decimals, dec_point, thousands_sep) {
        var n = number, prec = decimals;
    
        var toFixedFix = function (n,prec) {
            var k = Math.pow(10,prec);
            return (Math.round(n*k)/k).toString();
        };
    
        n = !isFinite(+n) ? 0 : +n;
        prec = !isFinite(+prec) ? 0 : Math.abs(prec);
        var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep;
        var dec = (typeof dec_point === 'undefined') ? '.' : dec_point;
    
        var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec);
        // Fix for Internet Explorer parseFloat(0.55).toFixed(0) = 0;
    
        var abs = toFixedFix(Math.abs(n), prec);
        var _, i;
    
        if (abs >= 1000) {
            _ = abs.split(/\D/);
            i = _[0].length % 3 || 3;
    
            _[0] = s.slice(0,i + (n < 0)) +
                   _[0].slice(i).replace(/(\d{3})/g, sep+'$1');
            s = _.join(dec);
        } else {
            s = s.replace('.', dec);
        }
    
        var decPos = s.indexOf(dec);
        if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec) {
            s += new Array(prec-(s.length-decPos-1)).join(0)+'0';
        }
        else if (prec >= 1 && decPos === -1) {
            s += dec+new Array(prec).join(0)+'0';
        }
        return s;
    }
    

    原文的 评论块 ,包含以下内容作为示例和应得荣誉)

    // Formats a number with grouped thousands
    //
    // version: 906.1806
    // discuss at: http://phpjs.org/functions/number_format
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +     input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +     improved by: davook
    // +     improved by: Brett Zamir (http://brett-zamir.me)
    // +     input by: Jay Klehr
    // +     improved by: Brett Zamir (http://brett-zamir.me)
    // +     input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *     example 10: number_format('1.20', 2);
    // *     returns 10: '1.20'
    // *     example 11: number_format('1.20', 4);
    // *     returns 11: '1.2000'
    // *     example 12: number_format('1.2000', 3);
    // *     returns 12: '1.200'
    
  • 这是一个非常有用的变量名。在 RAM 和带宽以 KB 为单位计算的时代,将其转换为 n 以便在定义时节省 3 个字符可能是必要的,但在 minifier 会在投入生产之前处理所有这些问题的时代,这只会造成混淆。其他巧妙的微优化至少值得商榷。

  • 这不是太糟糕 – +n || 0 是唯一看起来有点奇怪的东西(至少对我来说)。

  • 就此而言,我认为这可能优化过早,应该重构以提高可读性。但我的目标是增强 OP 的代码,而不是从根本上改变它。

  • 你说得对。这是我从 Jonathan M 的原文中引入的一个错误,其中它们都被链接为单个 var 表达式。这些应该是简单的赋值。正在修复。

  • 第一个 var 有点奇怪,因为这些变量已经在函数声明中声明了。除此之外,谢谢!

返回
作者最近主题: