【问题标题】:Format numbers in JavaScript similar to C#在 JavaScript 中格式化数字,类似于 C#
【发布时间】:2010-11-07 06:50:56
【问题描述】:

有没有一种在 JavaScript 中格式化数字的简单方法,类似于 C#(或 VB.NET)中通过 ToString("format_provider")String.Format() 提供的格式化方法?

【问题讨论】:

标签: javascript jquery format numbers


【解决方案1】:

一般情况

在 jQuery 中

【讨论】:

  • 一句警告:您链接到的 jQuery 数字格式化程序(我尝试使用 v1.1.0)完全损坏且无用。如:它根本不起作用。这是一个不错的格式化插件:asual.com/jquery/format
  • @Tomalak,您应该将其发布为答案。这绝对是我用过的最好的数字格式化插件。我希望在单元测试之外有文档。
  • @Tomalak 永远不会太晚。一年多后我在看这个!
  • 将近三年后的我!
  • autoNumeric 功能相当全面,最近更新到 1.8.0。
【解决方案2】:

首先,在 JS 中将整数转换为字符串非常简单:

// Start off with a number
var number = 42;
// Convert into a string by appending an empty (or whatever you like as a string) to it
var string = 42+'';
// No extra conversion is needed, even though you could actually do
var alsoString = number.toString();

如果您将数字作为字符串并希望将其转换为整数,则必须将 parseInt(string) 用于整数,将 parseFloat(string) 用于浮点数。然后这两个函数都返回所需的整数/浮点数。示例:

// Start off with a float as a string
var stringFloat = '3.14';
// And an int as a string
var stringInt = '42';

// typeof stringInt  would give you 'string'

// Get the real float from the string
var realFloat = parseFloat(someFloat);
// Same for the int
var realInt = parseInt(stringInt);

// but typeof realInt  will now give you 'number'

你到底想附加什么等等,我从你的问题中仍然不清楚。

【讨论】:

  • 谢谢。你在 jsfiddle 上查看过我的代码吗?我基本上了解如何将整数转换为字符串 - 因为我还不太精通 js,所以我不明白的是如何使用我正在使用的脚本的上下文来做到这一点。有什么进一步的见解吗?
  • @blackessej 我不明白昏迷后必须附加什么。如果只是计数,我建议使用浮点数,例如,如果您想要 2 个小数位,您可以简单地将数字每次增加 0.01,而不是 1。
  • 你真的不得不忍受我 - 我不明白如何在我的代码中将我的号码转换为字符串。
  • 请务必使用parseInt(..., 10),以确保使用基数10。
  • 不是问题的答案。他希望(我也希望)将XXXXXXX.YYYY 变成X,XXX,XXX.YYYY
【解决方案3】:

这是一个简单的 JS 函数,用于将逗号添加到字符串格式的整数中。它将处理整数或十进制数。您可以将其传递给数字或字符串。它显然返回一个字符串。

function addCommas(str) {
    var parts = (str + "").split("."),
        main = parts[0],
        len = main.length,
        output = "",
        first = main.charAt(0),
        i;

    if (first === '-') {
        main = main.slice(1);
        len = main.length;    
    } else {
        first = "";
    }
    i = len - 1;
    while(i >= 0) {
        output = main.charAt(i) + output;
        if ((len - i) % 3 === 0 && i > 0) {
            output = "," + output;
        }
        --i;
    }
    // put sign back
    output = first + output;
    // put decimal part back
    if (parts.length > 1) {
        output += "." + parts[1];
    }
    return output;
}

这是一组测试用例:http://jsfiddle.net/jfriend00/6y57j/

你可以在之前的 jsFiddle 中看到它被使用:http://jsfiddle.net/jfriend00/sMnjT/。您也可以通过简单的 Google 搜索“javascript add commas”找到处理十进制数字的函数。

可以通过多种方式将数字转换为字符串。最简单的就是将其添加到字符串中:

var myNumber = 3;
var myStr = "" + myNumber;   // "3"

在您的 jsFiddle 的上下文中,您可以通过更改此行将逗号放入计数器:

jTarget.text(current);

到这里:

jTarget.text(addCommas(current));

你可以在这里看到它的工作原理:http://jsfiddle.net/jfriend00/CbjSX/

【讨论】:

  • @blackessej - 我在答案的末尾添加了更多内容,显示了如何将 addCommas 添加到您的小提琴中。
  • addCommas() 函数中添加了对十进制数字的支持,因此它适用于带有小数部分的数字。
  • 对于负数来说不太热):
  • @Kristopher - 我添加了对负数的支持。
  • 非常好。我现在正在使用它。
【解决方案4】:

是的,肯定有办法在javascript中正确格式化数字,例如:

var val=2489.8237

val.toFixed(3) //returns 2489.824 (round up)
val.toFixed(2) //returns 2489.82
val.toFixed(7) //returns 2489.8237000 (padding)

使用变量名。toFixed

还有另一个函数 toPrecision() 。 更多详情,您还可以访问

http://raovishal.blogspot.com/2012/01/number-format-in-javascript.html

【讨论】:

    【解决方案5】:

    使用 JQuery

    $(document).ready(function()
     {
        //Only number and one dot
        function onlyDecimal(element, decimals)
        {
            $(element).keypress(function(event)
            {
                num = $(this).val() ;
                num = isNaN(num) || num === '' || num === null ? 0.00 : num ;
                if ((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57))
                {
                    event.preventDefault();
    
                }
                if($(this).val() == parseFloat(num).toFixed(decimals))
                {
                    event.preventDefault();
                }
            });
        }
    
         onlyDecimal("#TextBox1", 3) ;
    
    
    
    });
    

    【讨论】:

      【解决方案6】:

      如果你不想使用 jQuery,看看Numeral.js

      【讨论】:

        【解决方案7】:

        例如:

        var flt = '5.99';
        var nt = '6';
        
        var rflt = parseFloat(flt);
        var rnt = parseInt(nt);
        

        【讨论】:

          【解决方案8】:

          http://code.google.com/p/javascript-number-formatter/

          • 简短、快速、灵活且独立。只有 75 行,包括 MIT 许可证信息、空白行和 cmets。
          • 接受标准数字格式,如 #,##0.00 或否定 -000.####。
          • 接受任何国家/地区格式,例如 ###0,00、#、###.##、#'###.## 或任何类型的非编号符号。
          • 接受任意数量的数字分组。 #,##,#0.000 或 #,###0.## 都有效。
          • 接受任何冗余/防呆格式。 ##,###,##.# 或 0#,#00#.###0# 都可以。
          • 自动数字舍入。
          • 简单的界面,只需像这样提供掩码和值:格式(“0.0000”,3.141592)

          更新

          正如 Tomáš Zato 所说,这里有一种解决方案:

          (666.0).toLocaleString()
          numObj.toLocaleString([locales [, options]])
          

          ECMA-262 5.1 版中描述的:

          并且将在未来版本的浏览器中工作......

          【讨论】:

          • 因为我不想在只需要一个简单函数的时候使用库...?
          • 这个函数很简单:code.google.com/p/javascript-number-formatter/source/browse/… 吗?我认为 - 是的(60 行代码)。
          • 你说得非常正确“我认为”。那是因为事情是否简单是见仁见智的问题。意见中没有绝对的真理,这让我们有机会进行无休止的争论。
          • 这是 SO,您的行为在 SO 用户中很典型。
          • 看来你真的准备好对我的评论发火了。你没有更好的事情要做吗?无论如何,一个班轮越野代码是(6666.0).toLocaleString()。如果您知道此类 cmets 超出主题并且可能会消失,欢迎您随意调用任何行为。也请停止试图让我对你的帖子投反对票。你注定要失败,因为我没有投反对票……我更喜欢 cmets 而不是投反对票。
          【解决方案9】:

          这是另一个版本:

          $.fn.digits = function () {
              return this.each(function () {
                  var value = $(this).text();
                  var decimal = "";
                  if (value) {
                      var pos = value.indexOf(".");
                      if (pos >= 0) {
                          decimal = value.substring(pos);
                          value = value.substring(0, pos);
                      }
                      if (value) {
                          value = value.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
                          if (!String.isNullOrEmpty(decimal)) value = (value + decimal);
                          $(this).text(value);
                      }
                  }
                  else {
                      value = $(this).val()
                      if (value) {
                          var pos = value.indexOf(".");
                          if (pos >= 0) {
                              decimal = value.substring(pos);
                              value = value.substring(0, pos);
                          }
                          if (value) {
                              value = value.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
                              if (!String.isNullOrEmpty(decimal)) value = (value + decimal);
                              $(this).val(value);
                          }
                      }
                  }
              })
          };
          

          【讨论】:

            【解决方案10】:

            要获得逗号后有 2 个数字的小数,您可以使用:

            function nformat(a) {
               var b = parseInt(parseFloat(a)*100)/100;
               return b.toFixed(2);
            }
            

            【讨论】:

              【解决方案11】:

              这里有一些解决方案,都通过了测试套件,包括测试套件和基准测试,如果您想复制粘贴进行测试,请尝试This Gist

              方法 0(正则表达式)

              基于https://stackoverflow.com/a/14428340/1877620,但如果没有小数点则修正。

              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('.');
                  }
              }
              

              方法一

              if (typeof Number.prototype.format1 === 'undefined') {
                  Number.prototype.format1 = 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.format2 === 'undefined') {
                  Number.prototype.format2 = 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.format3 === 'undefined') {
                  Number.prototype.format3 = 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 ========')
              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');
              }
              
              async = [];
              function next() {
                  setTimeout(function () {
                      f = async.shift();
                      f && f();
                      next();
                  }, 10);
              }
              
              console.log('======== Benchmark ========');
              async.push(function () { benchmark_format(Number.prototype.format); });
              async.push(function () { benchmark_format(Number.prototype.format1); });
              async.push(function () { benchmark_format(Number.prototype.format2); });
              async.push(function () { benchmark_format(Number.prototype.format3); });
              next();
              

              【讨论】:

                【解决方案12】:

                我写了一个简单的函数(不需要另一个 jQuery 插件!!),如果数字不是以数字开头的数字,它可以将数字转换为小数分隔的字符串或空字符串:

                function format(x) {
                    return isNaN(x)?"":x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                }
                

                format(578999); 导致578,999

                format(10); 导致10

                如果您想使用小数点而不是逗号,只需将代码中的逗号替换为小数点即可。

                其中一个 cmets 正确地指出这仅适用于整数,通过一些小的修改您可以使其也适用于浮点数:

                function format(x) {
                    if(isNaN(x))return "";
                
                    n= x.toString().split('.');
                    return n[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")+(n.length>1?"."+n[1]:"");
                }
                

                【讨论】:

                • 如果先拆分浮点部分,然后用整数执行此操作,然后再次添加流动点部分,它也应该适用于 fp
                • "412.8".replace(/\B(?=(\d{3})+(?!\d))/g, ","); 返回412.8。我认为它可以返回412.80
                【解决方案13】:

                我做了一个简单的功能,也许有人可以使用它

                function secsToTime(secs){
                  function format(number){
                    if(number===0){
                      return '00';
                    }else {
                      if (number < 10) {
                          return '0' + number
                      } else{
                          return ''+number;
                      }
                    }
                  }
                
                  var minutes = Math.floor(secs/60)%60;
                  var hours = Math.floor(secs/(60*60))%24;
                  var days = Math.floor(secs/(60*60*24));
                  var seconds = Math.floor(secs)%60;
                
                  return (days>0? days+"d " : "")+format(hours)+':'+format(minutes)+':'+format(seconds);
                }
                

                这可以生成以下输出:

                • 5d 02:53:39
                • 4d 22:15:16
                • 03:01:05
                • 00:00:00

                【讨论】:

                  【解决方案14】:

                  如果您想格式化数字以供查看而不是用于计算,您可以使用此

                  function numberFormat( number ){
                  
                      var digitCount = (number+"").length;
                      var formatedNumber = number+"";
                      var ind = digitCount%3 || 3;
                      var temparr = formatedNumber.split('');
                  
                      if( digitCount > 3 && digitCount <= 6 ){
                  
                          temparr.splice(ind,0,',');
                          formatedNumber = temparr.join('');
                  
                      }else if (digitCount >= 7 && digitCount <= 15) {
                          var temparr2 = temparr.slice(0, ind);
                          temparr2.push(',');
                          temparr2.push(temparr[ind]);
                          temparr2.push(temparr[ind + 1]);
                          // temparr2.push( temparr[ind + 2] ); 
                          if (digitCount >= 7 && digitCount <= 9) {
                              temparr2.push(" million");
                          } else if (digitCount >= 10 && digitCount <= 12) {
                              temparr2.push(" billion");
                          } else if (digitCount >= 13 && digitCount <= 15) {
                              temparr2.push(" trillion");
                  
                          }
                          formatedNumber = temparr2.join('');
                      }
                      return formatedNumber;
                  }
                  

                  输入: {Integer} 数字

                  输出: {String} 数字

                  22,870 => 如果数字 22870

                  2287 万 => 如果数字 2287xxxx(x 可以是任何值)

                  228.7 亿 => 如果数字为 2287xxxxxxx

                  22,87 万亿 => 如果数字 2287xxxxxxxxxx

                  你懂的

                  【讨论】:

                    【解决方案15】:

                    为了进一步 jfriend00 的回答(我没有足够的评论点数),我将他/她的回答扩展到以下内容:

                    function log(args) {
                        var str = "";
                        for (var i = 0; i < arguments.length; i++) {
                            if (typeof arguments[i] === "object") {
                                str += JSON.stringify(arguments[i]);
                            } else {
                                str += arguments[i];
                            }
                        }
                        var div = document.createElement("div");
                        div.innerHTML = str;
                        document.body.appendChild(div);
                    }
                    
                    Number.prototype.addCommas = function (str) {
                        if (str === undefined) {
                        	str = this;
                        }
                        
                        var parts = (str + "").split("."),
                            main = parts[0],
                            len = main.length,
                            output = "",
                            first = main.charAt(0),
                            i;
                        
                        if (first === '-') {
                            main = main.slice(1);
                            len = main.length;    
                        } else {
                        	  first = "";
                        }
                        i = len - 1;
                        while(i >= 0) {
                            output = main.charAt(i) + output;
                            if ((len - i) % 3 === 0 && i > 0) {
                                output = "," + output;
                            }
                            --i;
                        }
                        // put sign back
                        output = first + output;
                        // put decimal part back
                        if (parts.length > 1) {
                            output += "." + parts[1];
                        }
                        return output;
                    }
                    
                    var testCases = [
                        1, 12, 123, -1234, 12345, 123456, -1234567, 12345678, 123456789,
                        -1.1, 12.1, 123.1, 1234.1, -12345.1, -123456.1, -1234567.1, 12345678.1, 123456789.1
                    ];
                     
                    for (var i = 0; i < testCases.length; i++) {
                    	log(testCases[i].addCommas());
                    }
                     
                    /*for (var i = 0; i < testCases.length; i++) {
                        log(Number.addCommas(testCases[i]));
                    }*/

                    【讨论】:

                      【解决方案16】:

                      我建议numbro 用于基于区域设置的格式,number-format.js 用于一般情况。根据用例将两者结合起来可能会有所帮助。

                      【讨论】:

                        【解决方案17】:

                        您可以通过以下方式进行操作: 因此,您不仅可以格式化数字,还可以将要显示的小数位数作为参数传递,您可以设置自定义小数和英里分隔符。

                        function format(number, decimals = 2, decimalSeparator = '.', thousandsSeparator = ',') {
                            const roundedNumber = number.toFixed(decimals);
                            let integerPart = '', fractionalPart = '';
                            if (decimals == 0) {
                                integerPart = roundedNumber;
                                decimalSeparator = '';
                            } else {
                                let numberParts = roundedNumber.split('.');
                                integerPart = numberParts[0];
                                fractionalPart = numberParts[1];
                            }
                            integerPart = integerPart.replace(/(\d)(?=(\d{3})+(?!\d))/g, `$1${thousandsSeparator}`);
                            return `${integerPart}${decimalSeparator}${fractionalPart}`;
                        }
                        

                        用途:

                        let min = 1556454.0001;
                        let max = 15556982.9999;
                        console.time('number format');
                        for (let i = 0; i < 15000; i++) {
                            let randomNumber = Math.random() * (max - min) + min;
                        
                            let formated = format(randomNumber, 4, ',', '.'); // formated number
                        
                            console.debug('number: ', randomNumber, 'formated: ', formated);
                        }
                        console.timeEnd('number format');
                        

                        【讨论】:

                        • 记得在你检查if (decimals == 0) {的地方使用===而不是== - 它应该是if (decimals === 0) {
                        猜你喜欢
                        • 2011-03-11
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-12-10
                        • 2013-05-12
                        • 1970-01-01
                        • 2013-08-02
                        相关资源
                        最近更新 更多