JavaScript 是否考虑了本地小数点分隔符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12004808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:02:11  来源:igfitidea点击:

Does JavaScript take local decimal separators into account?

javascriptlocalization

提问by Stu Pegg

I've got a web page that displays decimals in a user's localized format, like so:

我有一个以用户本地化格式显示小数的网页,如下所示:

  • English: 7.75
  • Dutch: 7,75
  • 英语: 7.75
  • 荷兰语: 7,75

If I add two number variables together in JavaScript on my machine (where the numbers are taken from strings in the above formats) I get the following results:

如果我在机器上的 JavaScript 中将两个数字变量相加(其中数字取自上述格式的字符串),我会得到以下结果:

  • English: 7.75 + 7.75 = 15.5
  • Dutch: 7,75 + 7,75 = 0
  • 英语: 7.75 + 7.75 = 15.5
  • 荷兰语: 7,75 + 7,75 = 0

If I was to run this code on a Dutch users machine, should I expect the English-formatted addition to return 0, and the Dutch-formatted addition to return 15,5?

如果我要在荷兰用户机器上运行此代码,我是否应该期待英语格式的添加返回0,荷兰语格式的添加返回15,5

In short: Does the JavaScript calculation use local decimal separators in its string to number conversions?

简而言之:JavaScript 计算是否在其字符串中使用本地小数分隔符进行数字转换?

回答by naitsirch

Here's an example for a locale aware number parser:

这是区域设置感知数字解析器的示例:

function parseLocaleNumber(stringNumber) {
    var thousandSeparator = (1111).toLocaleString().replace(/1/g, '');
    var decimalSeparator = (1.1).toLocaleString().replace(/1/g, '');

    return parseFloat(stringNumber
        .replace(new RegExp('\' + thousandSeparator, 'g'), '')
        .replace(new RegExp('\' + decimalSeparator), '.')
    );
}

It uses the current locale of the browser to replace thousand and decimal separators.

它使用浏览器的当前语言环境来替换千位和小数分隔符。

With a German locale setting

使用德语区域设置

var n = parseLocaleNumber('1.000.045,22');

nwill be equal to 1000045.22.

n将等于1000045.22

回答by KooiInc

No, the separator is always a dot (.) in a javascript Number. So 7,75evaluates to 75, because a ,invokes left to right evaluation (try it in a console: x=1,x+=1,alert(x), or more to the point var x=(7,75); alert(x);). If you want to convert a Dutch (well, not only Dutch, let's say ContinentalEuropean) formatted value, it should be a String. You could write an extension to the Stringprototype, something like:

不,分隔符始终是 javascript 中的点 (.) Number。所以7,75评估为75,因为 a,调用从左到右的评估(在控制台中尝试:x=1,x+=1,alert(x),或者更重要的是var x=(7,75); alert(x);)。如果你想转换一个荷兰语(嗯,不仅仅是荷兰语,比如说欧洲大陆)格式的值,它应该是一个String. 您可以为String原型编写扩展,例如:

String.prototype.toFloat = function(){
      return parseFloat(this.replace(/,(\d+)$/,'.'));
};
//usage
'7,75'.toFloat()+'7,75'.toFloat(); //=> 15.5

Note, if the browser supports it you can use Number.toLocaleString

请注意,如果浏览器支持,您可以使用 Number.toLocaleString

console.log((3.32).toLocaleString("nl-NL"));
console.log((3.32).toLocaleString("en-UK"));
.as-console-wrapper { top: 0; max-height: 100% !important; }

回答by Tomasz Nurkiewicz

No, comma (,) is an operator having special meaning, just like dot (.). Otherwise things as simple as:

不,逗号( ,) 是一个具有特殊含义的运算符,就像点( .) 一样。否则事情很简单:

var array1 = [1,2];
var array2 = [1.2];

would break under different locales. All mainstream languages I know treat .and ,separately and stricly, irrespective to locale.

会在不同的语言环境下中断。所有的主流语言,我知道治疗.,单独和stricly,不论到语言环境。

回答by Jukka K. Korpela

No, decimal separators are not localized at all in JavaScript, and parseFloat() parses numbers in the same format as you need to use in JavaScript source code: “.” as decimal separator, no group (thousands) separator, “E” or “e” as “times ten to power” symbol, and Ascii hyphen “-” as minus sign.

不,小数点分隔符在 JavaScript 中根本没有本地化,并且 parseFloat() 解析数字的格式与您需要在 JavaScript 源代码中使用的格式相同:“。” 作为小数点分隔符,没有组(千)分隔符,“E”或“e”作为“十次幂”符号,以及 Ascii 连字符“-”作为减号。

To read or write numbers in localized format, you need something else. I would recommend the Globalize.js library, unless you can limit yourself to the single issue of decimal separator and a limited number of languages—in that case, it might be simpler to do just string manipulation that maps “.” to “,” on output and vice versa on input.

要以本地化格式读取或写入数字,您还需要其他东西。我会推荐 Globalize.js 库,除非您可以将自己限制在小数点分隔符的单一问题和有限数量的语言中——在这种情况下,只执行映射“.”的字符串操作可能会更简单。到“,”在输出上,反之亦然在输入上。

回答by OXiGEN

Expanding on the solution from @naitsirch we can use Intl.NumberFormat.formatToParts()to have JS parse the group and decimal separators.

扩展@naitsirch 的解决方案,我们可以使用Intl.NumberFormat.formatToParts()让 JS 解析组和小数分隔符。

function parseLocaleNumber(stringNumber) {
  let num = 123456.789,
    fmt_local = new Intl.NumberFormat(),
    parts_local = fmt_local.formatToParts(num),
    group = '',
    decimal = '';

  parts_local.forEach(function(i) {
    switch (i.type) {
      case 'group':
        group = i.value;
        break;
      case 'decimal':
        decimal = i.value;
        break;
      default:
        break;
    }
  });

  return parseFloat(stringNumber
    .replace(new RegExp('\' + group, 'g'), '')
    .replace(new RegExp('\' + decimal), '.')
  );
}

//replace this string with a number formatted for your locale
console.log(parseLocaleNumber("987,654,321.01"));
//output for "en" locale: 987654321.01

回答by Andres A.

Taking the symbol into account, this works in all cases:

考虑到符号,这适用于所有情况:

parseLocaleNumber: function ( stringNumber ) 
{
    let thousandSeparator = (11111).toLocaleString().replace(/1/g, '');
    let decimalSeparator = (1.1).toLocaleString().replace(/1/g, '');
    let symbol = (0).toLocaleString()
        .replace(/0/g, '')
        .replace(new RegExp('\' + decimalSeparator), '.')
        .trim();

    return parseFloat(
        stringNumber
            .replace(new RegExp('\' + thousandSeparator, 'g'), '')
            .replace(new RegExp('\' + decimalSeparator), '.')
            .replace(new RegExp( symbol ), '')
    );
}

2 details highlighted:

突出显示2个细节:

  1. use 11111 instead of 1111 because the first always shows thousand separator by default.
  2. Number format always uses '.' as decimal separator
  1. 使用 11111 而不是 1111 因为第一个默认总是显示千位分隔符。
  2. 数字格式始终使用“.” 作为小数点分隔符

回答by Raoul L?ttem?e

Expanding on the solution from @OXiGEN we can use Intl.NumberFormat.formatToParts()to extract also the currency symbol :)

扩展来自@OXiGEN 的解决方案,我们可以使用Intl.NumberFormat.formatToParts()来提取货币符号:)

parseLocaleNumber(stringNumber, locale, currency_code) {
    let num = 123456.789,
    fmt_local = new Intl.NumberFormat(locale, {
        style: "currency",
        currency: currency_code
        }),
    parts_local = fmt_local.formatToParts(num),
    group = '',
    decimal = '',
    currency = '';

    // separators
    parts_local.forEach(function(i) {
        //console.log(i.type + ':' + i.value);
        switch (i.type) {
            case 'group':
                group = i.value;
                break;
            case 'decimal':
                decimal = i.value;
                break;
            case 'currency':
                currency = i.value;
                break;
            default:
                break;
        }
    });

    return parseFloat(stringNumber
        .replace(new RegExp('\' + group, 'g'), '')
        .replace(new RegExp('\' + decimal), '.')
        .replace(new RegExp('\' + currency, 'g'), '')
    );
}