Как я могу отформатировать числа в виде строки валюты в JavaScript? - PullRequest
1578 голосов
/ 29 сентября 2008

Я бы хотел отформатировать цену в JavaScript.
Я хотел бы функцию, которая принимает float в качестве аргумента и возвращает string в следующем формате:

"$ 2,500.00"

Какой лучший способ сделать это?

Ответы [ 62 ]

7 голосов
/ 29 сентября 2008

Кодовая база YUI использует следующий формат:

format: function(nData, oConfig) {
    oConfig = oConfig || {};

    if(!YAHOO.lang.isNumber(nData)) {
        nData *= 1;
    }

    if(YAHOO.lang.isNumber(nData)) {
        var sOutput = nData + "";
        var sDecimalSeparator = (oConfig.decimalSeparator) ? oConfig.decimalSeparator : ".";
        var nDotIndex;

        // Manage decimals
        if(YAHOO.lang.isNumber(oConfig.decimalPlaces)) {
            // Round to the correct decimal place
            var nDecimalPlaces = oConfig.decimalPlaces;
            var nDecimal = Math.pow(10, nDecimalPlaces);
            sOutput = Math.round(nData*nDecimal)/nDecimal + "";
            nDotIndex = sOutput.lastIndexOf(".");

            if(nDecimalPlaces > 0) {
                // Add the decimal separator
                if(nDotIndex < 0) {
                    sOutput += sDecimalSeparator;
                    nDotIndex = sOutput.length-1;
                }
                // Replace the "."
                else if(sDecimalSeparator !== "."){
                    sOutput = sOutput.replace(".",sDecimalSeparator);
                }
                // Add missing zeros
                while((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) {
                    sOutput += "0";
                }
            }
        }

        // Add the thousands separator
        if(oConfig.thousandsSeparator) {
            var sThousandsSeparator = oConfig.thousandsSeparator;
            nDotIndex = sOutput.lastIndexOf(sDecimalSeparator);
            nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length;
            var sNewOutput = sOutput.substring(nDotIndex);
            var nCount = -1;
            for (var i=nDotIndex; i>0; i--) {
                nCount++;
                if ((nCount%3 === 0) && (i !== nDotIndex)) {
                    sNewOutput = sThousandsSeparator + sNewOutput;
                }
                sNewOutput = sOutput.charAt(i-1) + sNewOutput;
            }
            sOutput = sNewOutput;
        }

        // Prepend prefix
        sOutput = (oConfig.prefix) ? oConfig.prefix + sOutput : sOutput;

        // Append suffix
        sOutput = (oConfig.suffix) ? sOutput + oConfig.suffix : sOutput;

        return sOutput;
    }
    // Still not a Number, just return unaltered
    else {
        return nData;
    }
}

это нужно будет отредактировать, так как библиотека YUI настраивается, например, замена oConfig.decimalSeparator на "."

6 голосов
/ 20 января 2019

Number(value)
        .toFixed(2)
        .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
6 голосов
/ 04 мая 2015

@ tggagne - это правильно. Мое решение ниже не является хорошим из-за округления поплавка. А функции toLocaleString не хватает некоторой поддержки браузера. Я оставлю комментарии ниже для архивных целей того, что НЕ нужно делать. :)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString#Browser_Compatibility

(старое решение) Вместо этого используйте раствор Патрика Дежардена.

Это краткое решение, использующее toLocaleString (), которое поддерживается с версии 1.0 Javascript. В этом примере валюта указана в долларах США, но ее можно перевести в фунты, используя вместо фунта «доллары».

var formatMoney = function (value) {
    // Convert the value to a floating point number in case it arrives as a string.
    var numeric = parseFloat(value);
    // Specify the local currency.
    return numeric.toLocaleString('USD', { style: 'currency', currency: "USD", minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

Подробнее см. https://marcoscaceres.github.io/jsi18n/#localize_currency.

6 голосов
/ 20 мая 2014

Функция для обработки валюты, включая негативы.

Пример вывода:
5,23 $
- $ 5,23

function formatCurrency(total) {
    var neg = false;
    if(total < 0) {
        neg = true;
        total = Math.abs(total);
    }
    return (neg ? "-$" : '$') + parseFloat(total, 10).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").toString();
}
6 голосов
/ 22 октября 2015

55 ответов явно просят другого

        function centsToDollaString(x){
          var cents = x + ""
          while(cents.length < 4){
            cents = "0" + cents;
          }
          var dollars = cents.substr(0,cents.length - 2)
          var decimal = cents.substr(cents.length - 2, 2)
          while(dollars.length % 3 != 0){
            dollars = "0" + dollars;
          }
          str = dollars.replace(/(\d{3})(?=\d)/g, "$1" + ",").replace(/^0*(?=.)/,"");
          return "$" + str + "." + decimal;
        }
5 голосов
/ 10 сентября 2014

Intl.NumberFormat

var number = 3500;
alert(new Intl.NumberFormat().format(number));
// → "3,500" if in US English locale

или phpjs.com / functions / number_format

5 голосов
/ 15 января 2013

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

  • Короткий, быстрый, гибкий, но автономный. Всего 75 строк, включая информацию о лицензии MIT, пустые строки и комментарии.
  • Принимать стандартное форматирование чисел, например #, ## 0,00 или с отрицанием -000. ####.
  • Примите любой формат страны, например # ## 0,00, #, ###. ##, # '###. ## или любой тип не нумерации символов.
  • Принимайте любые цифры группировки цифр. #, ##, # 0.000 или #, ### 0. ## все действительны.
  • Примите любое избыточное / надежное форматирование. ##, ###, ##. # или 0 #, # 00 #. ### 0 # все в порядке.
  • Авто округление числа.
  • Простой интерфейс, просто введите маску и значение следующим образом: формат ("0.0000", 3.141592)

ОБНОВЛЕНИЕ Это мои доморощенные pp утилиты для самых распространенных задач:

var NumUtil = {};

/**
  Petty print 'num' wth exactly 'signif' digits.
  pp(123.45, 2) == "120"
  pp(0.012343, 3) == "0.0123"
  pp(1.2, 3) == "1.20"
*/
NumUtil.pp = function(num, signif) {
    if (typeof(num) !== "number")
        throw 'NumUtil.pp: num is not a number!';
    if (isNaN(num))
        throw 'NumUtil.pp: num is NaN!';
    if (num < 1e-15 || num > 1e15)
        return num;
    var r = Math.log(num)/Math.LN10;
    var dot = Math.floor(r) - (signif-1);
    r = r - Math.floor(r) + (signif-1);
    r = Math.round(Math.exp(r * Math.LN10)).toString();
    if (dot >= 0) {
        for (; dot > 0; dot -= 1)
            r += "0";
        return r;
    } else if (-dot >= r.length) {
        var p = "0.";
        for (; -dot > r.length; dot += 1) {
            p += "0";
        }
        return p+r;
    } else {
        return r.substring(0, r.length + dot) + "." + r.substring(r.length + dot);
    }
}

/** Append leading zeros up to 2 digits. */
NumUtil.align2 = function(v) {
    if (v < 10)
        return "0"+v;
    return ""+v;
}
/** Append leading zeros up to 3 digits. */
NumUtil.align3 = function(v) {
    if (v < 10)
        return "00"+v;
    else if (v < 100)
        return "0"+v;
    return ""+v;
}

NumUtil.integer = {};

/** Round to integer and group by 3 digits. */
NumUtil.integer.pp = function(num) {
    if (typeof(num) !== "number") {
        console.log("%s", new Error().stack);
        throw 'NumUtil.integer.pp: num is not a number!';
    }
    if (isNaN(num))
        throw 'NumUtil.integer.pp: num is NaN!';
    if (num > 1e15)
        return num;
    if (num < 0)
        throw 'Negative num!';
    num = Math.round(num);
    var group = num % 1000;
    var integ = Math.floor(num / 1000);
    if (integ === 0) {
        return group;
    }
    num = NumUtil.align3(group);
    while (true) {
        group = integ % 1000;
        integ = Math.floor(integ / 1000);
        if (integ === 0)
            return group + " " + num;
        num = NumUtil.align3(group) + " " + num;
    }
    return num;
}

NumUtil.currency = {};

/** Round to coins and group by 3 digits. */
NumUtil.currency.pp = function(amount) {
    if (typeof(amount) !== "number")
        throw 'NumUtil.currency.pp: amount is not a number!';
    if (isNaN(amount))
        throw 'NumUtil.currency.pp: amount is NaN!';
    if (amount > 1e15)
        return amount;
    if (amount < 0)
        throw 'Negative amount!';
    if (amount < 1e-2)
        return 0;
    var v = Math.round(amount*100);
    var integ = Math.floor(v / 100);
    var frac = NumUtil.align2(v % 100);
    var group = integ % 1000;
    integ = Math.floor(integ / 1000);
    if (integ === 0) {
        return group + "." + frac;
    }
    amount = NumUtil.align3(group);
    while (true) {
        group = integ % 1000;
        integ = Math.floor(integ / 1000);
        if (integ === 0)
            return group + " " + amount + "." + frac;
        amount = NumUtil.align3(group) + " " + amount;
    }
    return amount;
}
4 голосов
/ 26 июня 2014

Код от Jonathan M выглядит сложным для меня, поэтому я переписал его и получил около 30% на FF v30 и 60% на Chrome v35.

Number.prototype.formatNumber = function(decPlaces, thouSeparator, decSeparator) {
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator == undefined ? "." : decSeparator;
    thouSeparator = thouSeparator == undefined ? "," : thouSeparator;

    var n = this.toFixed(decPlaces);
    if (decPlaces) {
        var i = n.substr(0, n.length - (decPlaces + 1));
        var j = decSeparator + n.substr(-decPlaces);
    } else {
        i = n;
        j = '';
    }

    function reverse(str) {
        var sr = '';
        for (var l = str.length - 1; l >= 0; l--) {
            sr += str.charAt(l);
        }
        return sr;
    }

    if (parseInt(i)) {
        i = reverse(reverse(i).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator));
    }
    return i+j;
};

Использование:

var sum = 123456789.5698;
var formatted = '$' + sum.formatNumber(2,',','.'); // "$123,456,789.57"
4 голосов
/ 22 октября 2014

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat Пример: использование локалей

В этом примере показаны некоторые различия в форматах локализованных номеров. Чтобы получить формат языка, используемого в пользовательском интерфейсе вашего приложения, обязательно укажите этот язык (и, возможно, некоторые запасные языки), используя аргумент locales:

var number = 123456.789;

// Немецкий язык использует запятую в качестве десятичного разделителя и точку для тысяч console.log (новый Intl.NumberFormat ('de-DE'). format (number)); // → 123.456,789

// В большинстве арабских стран арабский язык использует настоящие арабские цифры console.log (новый Intl.NumberFormat ('ar-EG'). format (number)); // → 123456. 789

// Индия использует разделители тысяч / лак / крор console.log (new Intl.NumberFormat ( 'ен-IN') формате (номер));.

4 голосов
/ 21 января 2014

Вот самый короткий и лучший способ конвертировать числа в формат валюты:

function toCurrency(amount){
    return amount.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
}

// usage: toCurrency(3939920.3030);

Ура! Anunay

...