Как отформатировать числа в виде строки валюты?

1849

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

"$ 2,500.00"

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

Daniel Magliola
источник
8
В formatNumberjavascript нет встроенной функции
zerkms
500
Пожалуйста, для тех, кто читает это в будущем, не используйте float для хранения валюты. Вы потеряете точность и данные. Вы должны хранить его как целое число центов (или пенни и т. Д.), А затем конвертировать до вывода.
Филип Уайтхаус
8
@ user1308743 Float не хранит десятичные разряды. Он хранит числа с использованием значения, базы и смещения. 0,01 на самом деле не представимо. См .: en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Филип Уайтхаус
6
@ user1308743: представьте, что вы представляете очень большое число (допустим, вы счастливчик, и это остаток на вашем банковском счете). Вы действительно хотите потерять деньги из-за недостатка точности?
2012 г.
163
Так почему никто не предложил следующее? (2500) .toLocaleString ("en-GB", {стиль: "валюта", валюта: "GBP", минимумFractionDigits: 2}) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ник Грэйли

Ответы:

1793

Number.prototype.toFixed

Это решение совместимо с каждым основным браузером:

  const profits = 2489.8237;

  profits.toFixed(3) //returns 2489.824 (rounds up)
  profits.toFixed(2) //returns 2489.82
  profits.toFixed(7) //returns 2489.8237000 (pads the decimals)

Все, что вам нужно, это добавить символ валюты (например "$" + profits.toFixed(2)), и вы получите свою сумму в долларах.

Пользовательская функция

Если вам требуется использовать ,между каждой цифрой, вы можете использовать эту функцию:

function formatMoney(number, decPlaces, decSep, thouSep) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
decSep = typeof decSep === "undefined" ? "." : decSep;
thouSep = typeof thouSep === "undefined" ? "," : thouSep;
var sign = number < 0 ? "-" : "";
var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces)));
var j = (j = i.length) > 3 ? j % 3 : 0;

return sign +
	(j ? i.substr(0, j) + thouSep : "") +
	i.substr(j).replace(/(\decSep{3})(?=\decSep)/g, "$1" + thouSep) +
	(decPlaces ? decSep + Math.abs(number - i).toFixed(decPlaces).slice(2) : "");
}

document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

Используйте это так:

(123456789.12345).formatMoney(2, ".", ",");

Если вы всегда собираетесь использовать «.» и ',', вы можете оставить их вне вашего вызова метода, и метод по умолчанию выберет их для вас.

(123456789.12345).formatMoney(2);

Если в вашей культуре два символа перевернуты (т. Е. Европейцы), и вы хотите использовать значения по умолчанию, просто вставьте следующие две строки в formatMoneyметод:

    d = d == undefined ? "," : d, 
    t = t == undefined ? "." : t, 

Пользовательская функция (ES6)

Если вы можете использовать современный синтаксис ECMAScript (например, через Babel), вы можете использовать эту более простую функцию:

function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {
  try {
    decimalCount = Math.abs(decimalCount);
    decimalCount = isNaN(decimalCount) ? 2 : decimalCount;

    const negativeSign = amount < 0 ? "-" : "";

    let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
    let j = (i.length > 3) ? i.length % 3 : 0;

    return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
  } catch (e) {
    console.log(e)
  }
};
document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

хайкам
источник
26
прежде всего отличный, лаконичный код. однако, если вы американец, вы должны изменить значения по умолчанию dи tбыть .и ,соответственно, чтобы вам не приходилось указывать их каждый раз. Кроме того, я рекомендую изменить начало returnоператора следующим образом: return s + '$' + [rest]иначе вы не получите знак доллара.
Джейсон
744
Не уверен, почему люди считают этот код красивым. Это неразборчиво. Вроде хорошо работает, но не красиво.
USR
86
Эта функция formatMoney скопирована из какого-то уменьшенного кода JavaScript где-нибудь? Вы не можете опубликовать оригинал? Что обозначают переменные c, d, i, j, n, s и t? Судя по количеству комментариев и комментариев, я могу предположить, что этот код был скопирован и вставлен на рабочие сайты повсюду ... Удачи в сохранении кода, если в нем когда-нибудь будет ошибка!
Зуаллауз
259
«поэзия»? Больше похоже на безвестность. Это не код гольф; использовать немного пустого пространства. Правильные имена вар тоже не помешают.
keithjgrant
1517

Intl.numberformat

Javascript имеет средство форматирования чисел (часть Интернационализации API).

// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});

formatter.format(2500); /* $2,500.00 */

JS скрипка

Использовать undefinedвместо первого аргумента ('en-US' в примере), чтобы использовать системный языковой стандарт (пользовательский языковой стандарт, если код выполняется в браузере). Дальнейшее объяснение кода локали .

Вот список кодов валют .

Intl.NumberFormat vs Number.prototype.toLocaleString

Последнее замечание, сравнивающее это со старшим. toLocaleString, Они оба предлагают по существу одинаковую функциональность. Однако toLocaleString в его более старых версиях (pre-Intl) фактически не поддерживает локали : он использует системную локаль. Поэтому убедитесь, что вы используете правильную версию ( MDN предлагает проверить наличиеIntl ). Кроме того, производительность обоих одинакова для одного элемента, но если у вас много чисел для форматирования, использование Intl.NumberFormatпроисходит в ~ 70 раз быстрее. Вот как использовать toLocaleString:

(2500).toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
}); /* $2,500.00 */

Некоторые замечания по поддержке браузера

  • В настоящее время поддержка браузеров больше не является проблемой: 97,5% поддерживаются во всем мире, 98% в США и 99% в ЕС
  • Существует прокладка , чтобы поддержать его на окаменели браузеры (как IE8), вы должны действительно нужны
  • Посмотрите на CanIUse для получения дополнительной информации
aross
источник
89
Это идиоматическое JavaScript, простое и элегантное решение - именно то, что я искал.
Гилхем Сулас
9
Голосую за этот, потому что это глупо простой ответ, который работает изначально.
Трасива
17
Я уверен, что довольно высокий процент браузеров теперь поддерживают это. Это должно быть одобрено гораздо больше.
FLQ
2
Это отличный ответ, и у меня он работает с динамическим значением валюты, поэтому, если он используется в Европе, он меняется на евро и показывает знак евро. Работает угощение!
Спрос
3
Это 2018 год, и это в основном поддерживается везде. Это должен быть правильный ответ.
Саринк
1340

Краткое и быстрое решение (работает везде!)

(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');  // 12,345.67

Идея этого решения заменить совпавшие секции с первым матчем и запятой, то есть '$&,'. Сопоставление выполняется с использованием подхода «упреждения» . Вы можете прочитать выражение как «соответствовать номеру, если за ним следует последовательность из трех наборов чисел (один или несколько) и точка» .

ИСПЫТАНИЯ:

1        --> "1.00"
12       --> "12.00"
123      --> "123.00"
1234     --> "1,234.00"
12345    --> "12,345.00"
123456   --> "123,456.00"
1234567  --> "1,234,567.00"
12345.67 --> "12,345.67"

ДЕМО: http://jsfiddle.net/hAfMM/9571/


Расширенное короткое решение

Вы также можете расширить прототип Numberобъекта, чтобы добавить дополнительную поддержку любого количества десятичных знаков [0 .. n]и размера групп чисел [0 .. x]:

/**
 * Number.prototype.format(n, x)
 * 
 * @param integer n: length of decimal
 * @param integer x: length of sections
 */
Number.prototype.format = function(n, x) {
    var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
    return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
};

1234..format();           // "1,234"
12345..format(2);         // "12,345.00"
123456.7.format(3, 2);    // "12,34,56.700"
123456.789.format(2, 4);  // "12,3456.79"

ДЕМО / ИСПЫТАНИЯ: http://jsfiddle.net/hAfMM/435/


Супер расширенное короткое решение

В этой расширенной версии вы можете установить различные типы разделителей:

/**
 * Number.prototype.format(n, x, s, c)
 * 
 * @param integer n: length of decimal
 * @param integer x: length of whole part
 * @param mixed   s: sections delimiter
 * @param mixed   c: decimal delimiter
 */
Number.prototype.format = function(n, x, s, c) {
    var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
        num = this.toFixed(Math.max(0, ~~n));

    return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
};

12345678.9.format(2, 3, '.', ',');  // "12.345.678,90"
123456.789.format(4, 4, ' ', ':');  // "12 3456:7890"
12345678.9.format(0, 3, '-');       // "12-345-679"

ДЕМО / ИСПЫТАНИЯ: http://jsfiddle.net/hAfMM/612/

VisioN
источник
21
Я на самом деле пошел еще дальше: .replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,").
kalisjoshua
4
Версия CoffeeScript с регулярным выражением VisioN & kalisjoshua и способом указания десятичного знака (так что вы можете оставить значение по умолчанию 2 или указать 0 без десятичного знака):Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
Эрик Андерсон
11
@Abbas Да, заменить \.с $(конец строки), то есть this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,").
VisioN
2
@hanumant Регулярная грамматика здесь немного сложна, поэтому я предлагаю вам сначала прочитать руководства по регулярным выражениям (например, в MDN ). Идея это меняет совпавшие секции с первым матчем и запятой, то есть $1,. Сопоставление выполняется с использованием подхода «упреждения» . Вы можете прочитать выражение как «соответствовать номеру, если за ним следует последовательность из трех наборов чисел (один или несколько) и точка» .
VisioN
2
@ JuliendePrabère Пожалуйста, приведите пример длинного числа, которое не работает с этим подходом.
VisioN
248

Посмотрите на объект JavaScript Number и посмотрите, может ли он вам помочь.

  • toLocaleString() отформатирует число с использованием разделителя тысяч, определяемого местоположением.
  • toFixed() округляет число до определенного количества десятичных знаков.

Чтобы использовать их одновременно, значение должно изменить свой тип на число, потому что они оба выводят строку.

Пример:

Number((someNumber).toFixed(1)).toLocaleString()
17 из 26
источник
2
Спасибо! Основываясь на этой идее, я смог сделать ее достаточно короткой и простой! (и локализовано) Отлично.
Даниэль Маглиола
7
На самом деле Вы можете. то есть для долларов: '$' + (значение + 0,001) .toLocaleString (). slice (0, -1)
Zaptree
6
Похоже, это было бы замечательно, но в настоящее время поддержка браузеров незначительна
acorncom
1
@acorncom Почему вы говорите, что "небольшая поддержка браузера"? Объект Number существует с Javascript 1.1. Пожалуйста, предоставьте ссылку, подтверждающую вашу претензию.
Дуг С
2
Следует позаботиться о том, чтобы существовала старая версия, в toLocaleStringкоторой используется языковой стандарт системы, и новая (несовместимая), которая поступает из ECMAScript Intl API. Объяснил здесь . Этот ответ, похоже, предназначен для старой версии.
aross
162

Ниже приведен код Patrick Desjardins (псевдоним Daok) с небольшим количеством добавленных комментариев и некоторыми незначительными изменениями:

/* 
decimal_sep: character used as deciaml separtor, it defaults to '.' when omitted
thousands_sep: char used as thousands separator, it defaults to ',' when omitted
*/
Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep)
{ 
   var n = this,
   c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal
   d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator)

   /*
   according to [/programming/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function]
   the fastest way to check for not defined parameter is to use typeof value === 'undefined' 
   rather than doing value === undefined.
   */   
   t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value

   sign = (n < 0) ? '-' : '',

   //extracting the absolute value of the integer part of the number and converting to string
   i = parseInt(n = Math.abs(n).toFixed(c)) + '', 

   j = ((j = i.length) > 3) ? j % 3 : 0; 
   return sign + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ''); 
}

и вот несколько тестов:

//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert(123456789.67392.toMoney() + '\n' + 123456789.67392.toMoney(3) + '\n' + 123456789.67392.toMoney(0) + '\n' + (123456).toMoney() + '\n' + (123456).toMoney(0) + '\n' + 89.67392.toMoney() + '\n' + (89).toMoney());

//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert((-123456789.67392).toMoney() + '\n' + (-123456789.67392).toMoney(-3));

Незначительные изменения:

  1. немного сдвинулся, Math.abs(decimals)чтобы быть сделано только тогда, когда нет NaN.

  2. decimal_sep больше не может быть пустой строкой (НЕОБХОДИМО какой-то десятичный разделитель)

  3. мы используем typeof thousands_sep === 'undefined' как предложено в разделе Как лучше определить, не передан ли аргумент в функцию JavaScript

  4. (+n || 0)не нужно, потому что thisэтоNumber объект

JS Fiddle

Marco Demaio
источник
8
Вы можете использовать «10» в качестве основы в parseInt. В противном случае любое число, начинающееся с «0», будет использовать восьмеричную нумерацию.
sohtimsso1970
3
@ sohtimsso1970: извините за поздний ответ, но не могли бы вы объяснить еще? Я не понимаю, где число можно интерпретировать как восьмеричное. parseIntНазывают по абсолютной величине целой части числа. Партия INTEGER не может начинаться с нуля, если только это не ноль! И parseInt(0) === 0восьмеричное, или десятичное.
Марко Демайо
try, например: parseInt ("016") ... возвращает 14, поскольку parseInt предполагает, что он восьмерично закодирован, когда строка начинается с нуля.
Tracker1
4
@ Tracker1: Я понял, что число, начинающееся с 0, считается восьмеричным parseInt. Но в этом коде это НЕВОЗМОЖНО для parseIntполучения в 016качестве входных данных (или любого другого восьмеричного отформатированного значения), поскольку передаваемый аргумент parseInt1-й обрабатывается Math.absфункцией. Таким образом, нет способа parseIntполучить число, начинающееся с нуля, если только это не ноль или 0.nn(где nnдесятичные дроби). Но оба 0и 0.nnстроки будут преобразованы parseIntв простой ноль, как предполагается.
Марко Демайо
Эта функция неверна:> (2030) .toMoney (0, '.', ''); <"2 03 0"
Антон П Робул
125

Если сумма это число, скажем -123, тогда

amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });

будет производить строку "-$123.00".

Вот полный рабочий пример .

cs01
источник
7
Этот ответ был почти у меня, но мне нужно было округлить его до ближайшей копейки. Это то, что я использовал сумма.toLocaleString ('en-GB', {стиль: 'валюта', валюта: 'GBP', MaximumFractionDigits: 2});
Нико
Приведенный выше код выполняет округление до необходимого количества цифр. См. Пример и введите 1.237 в поле ввода.
Даниэль Барбалас
3
Кажется, не работает в Safari. Он просто возвращает число в виде строки без какого-либо форматирования.
Ланс Андерсон
1
Вау, это действительно отличный ответ. Должно быть сверху.
Итан
2
Если по какой-то причине вам не нужны центы, вы можете изменить десятичную точность с помощью:minimumFractionDigits: 0
Horacio
124

accounting.js - это крошечная библиотека JavaScript для форматирования чисел, денег и валюты.

GasheK
источник
... просто не забудьте передать символ валюты, иначе в IE7 и IE8 произойдет ошибка, IE9 в любом случае хорош
вектор
2
Похоже, ошибка IE7 / IE8 исправлена.
Мат Шаффер
2
Это отличная библиотека, возможность передавать символ валюты также является хорошей идеей, поскольку все детали валюты содержатся в одном вызове / настройках функции
farinspace
2
Мне нравится тот факт, что вы можете сделать наоборот - передать отформатированную строку валюты и получить числовое значение.
Нил Монро,
2
accounting.js не поддерживается в последнее время. Один из недавних изменений - github.com/nashdot/accounting-js
RationalDev нравится GoFundMonica
99

Вот лучший форматер js money, который я видел:

Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator) {
    var n = this,
        decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
        decSeparator = decSeparator == undefined ? "." : decSeparator,
        thouSeparator = thouSeparator == undefined ? "," : thouSeparator,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "",
        j = (j = i.length) > 3 ? j % 3 : 0;
    return sign + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

Это было переформатировано и заимствовано отсюда: https://stackoverflow.com/a/149099/751484

Вам нужно будет указать свой собственный обозначение валюты (вы использовали $ выше).

Назовите это так (хотя обратите внимание, что для аргументов по умолчанию задано значение 2, запятая и точка, поэтому вам не нужно указывать аргументы, если вы предпочитаете):

var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
Jonathan M
источник
следите за знаком globals, i, j
hacklikecrack
6
@hacklikecrack, все переменные являются локальными; они в varзаявлении.
Джонатан М
3
извините, да, хотя вы меняете аргументы. Отступ! ;)
hacklikecrack
Ужасное использование имен переменных!
Серж Саган
77

Здесь уже есть несколько отличных ответов. Вот еще одна попытка, просто для удовольствия:

function formatDollar(num) {
    var p = num.toFixed(2).split(".");
    return "$" + p[0].split("").reverse().reduce(function(acc, num, i, orig) {
        return  num=="-" ? acc : num + (i && !(i % 3) ? "," : "") + acc;
    }, "") + "." + p[1];
}

И некоторые тесты:

formatDollar(45664544.23423) // "$45,664,544.23"
formatDollar(45) // "$45.00"
formatDollar(123) // "$123.00"
formatDollar(7824) // "$7,824.00"
formatDollar(1) // "$1.00"

Отредактировано: теперь оно будет обрабатывать и отрицательные числа

Уэйн Беркетт
источник
поэзия. блестящий. Вы пробовали использовать limitRight () developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…, который должен устранить обратную ()?
Стив
1
@ Steve - Вы правы, но вам нужно сделать что-то вроде i = orig.length - i - 1обратного вызова. Тем не менее, еще один обход массива.
Уэйн
11
Не о совместимости: reduceметод был представлен в Ecmascript 1.8 и не поддерживается в Internet Explorer 8 и ниже.
Блейз
Как сказал @Blaise, этот метод не будет работать в IE 8 или ниже.
rsbarro
Да, это правильно. Как отмечено в самом ответе, это просто для удовольствия. Кроме того, он должен нормально обрабатывать отрицательные числа.
Уэйн
76

Работает для всех текущих браузеров

Используется toLocaleStringдля форматирования валюты в ее чувствительном к языку представлении (с использованием кодов валют ISO 4217 ).

(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2}) 

Пример фрагментов кода южноафриканского рэнда для @avenmore

console.log((2500).toLocaleString("en-ZA", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> R 2 500,00
console.log((2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> ZAR 2,500.00

оборота Ник Грили
источник
1
Поскольку аргументы «locales» и «options» поддерживаются очень небольшим количеством браузеров, таких как Chrome 24, IE11 и Opera 15. Firefox, Safari и более ранние версии других по-прежнему не поддерживают его.
VisioN
3
Согласен, он не полностью поддерживается во всех браузерах (пока), но это все еще решение. (И, пожалуй, самое правильное решение, так как оно совместимо с неподдерживаемыми браузерами и является документированной функцией API Javascript.)
Ник Грейли,
1
Мне это нравится, и я счастлив, что он работает с группировкой индийских цифр.
MSC
7
Это полностью поддерживается с 2017 года и должно быть единственным правильным ответом
Евгений
1
Последний и самый лучший :) FF69, Chrome76 и т. Д. «R 2 500,00» - это не то, что мы используем здесь, это должно быть «R 2 500,00», так же, как en-GB.
avenmore
70

Я думаю, что вы хотите f.nettotal.value = "$" + showValue.toFixed(2);

раздавить
источник
@ раздавить это работает, но это больше не переносит расчеты в поле налога?
Рокко Тако
11
Как только вы добавите к нему знак $, это уже не число, а строка.
раздавить
Эта опция не ставит запятую между тысячами. :-(
Саймон Ист
29

Numeral.js - библиотека js для простого форматирования чисел @adamwdraper

numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
Ярин
источник
Вилка Numbro, кажется, получает больше любви, поскольку Numeral.js кажется заброшенным: github.com/foretagsplatsen/numbro
RationalDev нравится GoFundMonica
Numeral.js снова активен.
adamwdraper
27

Хорошо, основываясь на том, что вы сказали, я использую это:

var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1);

var AmountWithCommas = Amount.toLocaleString();
var arParts = String(AmountWithCommas).split(DecimalSeparator);
var intPart = arParts[0];
var decPart = (arParts.length > 1 ? arParts[1] : '');
decPart = (decPart + '00').substr(0,2);

return '£ ' + intPart + DecimalSeparator + decPart;

Я открыт для предложений по улучшению (я бы предпочел не включать YUI только для этого :-)) Я уже знаю, что должен обнаруживать "." вместо того, чтобы просто использовать его в качестве десятичного разделителя ...

Даниэль Маглиола
источник
8
Обратите внимание, что ваша версия не округляется до двух десятичных цифр. Например, 3.706 будет отформатирован как «£ 3.70», а не как «£ 3.71», как это должно быть.
Атес Горал
Да, это нормально в моем конкретном случае, так как суммы, с которыми я работаю, уже имеют не более 2 цифр. Причина, по которой мне нужно установить значение до 2 десятичных знаков, касается сумм без десятичных знаков или только с 1.
Даниэль Маглиола,
26

Я использую библиотеку Globalize (от Microsoft):

Это отличный проект для локализации чисел, валют и дат и их автоматического форматирования в соответствии с языком пользователя! ... и, несмотря на то, что это должно быть расширение jQuery, в настоящее время это 100% независимая библиотека. Я предлагаю всем вам попробовать! :)

daveoncode
источник
3
Вау, почему это не проголосовало больше? Большая стандартизированная библиотека для всех видов форматирования. Стандартные параметры форматирования с правильной глобализацией. Отличный ответ !!
pbarranis
Это все еще считается альфа-стадией, поэтому используйте осторожно, но отличная находка.
Нил Монро,
1
Больше не в альфа (или бета). Это кажется очень полезным, пока мы ждем, чтобы Safari соответствовал новому стандарту и IE <11 умер.
Гай Шалнат,
25

javascript-number-formatter (ранее в Google Code )

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

(отрывок из его README)

Goodeq
источник
23

+1 Джонатану М за предоставление оригинального метода. Поскольку это явно средство форматирования валюты, я пошел дальше и добавил символ валюты (по умолчанию «$») к выводу и добавил запятую по умолчанию в качестве разделителя тысяч. Если вы на самом деле не хотите использовать символ валюты (или разделитель тысяч), просто используйте «» (пустую строку) в качестве аргумента для него.

Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) {
    // check the args and supply defaults:
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator == undefined ? "." : decSeparator;
    thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
    currencySymbol = currencySymbol == undefined ? "$" : currencySymbol;

    var n = this,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "",
        j = (j = i.length) > 3 ? j % 3 : 0;

    return sign + currencySymbol + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};
XML
источник
Первый вариант довольно странный, так как эти переменные уже объявлены в объявлении функции. Кроме этого, спасибо!
Рич Брэдшоу,
2
Вы правы. Это ошибка, которую я привел из оригинала Джонатана М., где все они связаны как одно выражение var. Это должны быть простые задания. Закрепление.
XML
В этом отношении я думаю, что это, вероятно, преждевременно оптимизировано и должно быть реорганизовано для удобства чтения. Но моя цель состояла в том, чтобы расширить код ОП, а не изменить его в корне.
XML
Это не так уж плохо - +n || 0единственное, что кажется немного странным (для меня в любом случае).
Рич Брэдшоу
2
thisэто совершенно полезное имя переменной. Преобразование в nтак, чтобы вы могли сохранить 3 символа в определенное время, возможно, было необходимо в эпоху, когда ОЗУ и пропускная способность были подсчитаны в КБ, но это просто запутывает в эпоху, когда минимизатор позаботится обо всем этом, прежде чем он когда-либо попадет в производство. Другие умные микрооптимизации по крайней мере спорны.
XML
22

Существует порт JavaScript функции PHP "number_format".

Я считаю его очень полезным, так как он прост в использовании и узнаваем для разработчиков 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 IE 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'
DaMayan
источник
Это только одна правильная функция:> number_format (2030, 0, '.', '') <'2 030' Отлично! Спасибо
Антон П Робуль
21

Более короткий метод (для вставки пробела, запятой или точки) с регулярным выражением?

    Number.prototype.toCurrencyString=function(){
        return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
    }

    n=12345678.9;
    alert(n.toCurrencyString());
оборота Жюльен де Прабер
источник
20

Ничего подобного не видел. Это довольно кратко и легко понять.

function moneyFormat(price, sign = '$') {
  const pieces = parseFloat(price).toFixed(2).split('')
  let ii = pieces.length - 3
  while ((ii-=3) > 0) {
    pieces.splice(ii, 0, ',')
  }
  return sign + pieces.join('')
}

console.log(
  moneyFormat(100),
  moneyFormat(1000),
  moneyFormat(10000.00),
  moneyFormat(1000000000000000000)
)

Вот версия с большим количеством опций в конечном выводе, позволяющая форматировать разные валюты в разных форматах местности.

// higher order function that takes options then a price and will return the formatted price
const makeMoneyFormatter = ({
  sign = '$',
  delimiter = ',',
  decimal = '.',
  append = false,
  precision = 2,
  round = true,
  custom
} = {}) => value => {
  
  const e = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
  
  value = round
    ? (Math.round(value * e[precision]) / e[precision])
    : parseFloat(value)
  
  const pieces = value
    .toFixed(precision)
    .replace('.', decimal)
    .split('')
  
  let ii = pieces.length - (precision ? precision + 1 : 0)
  
  while ((ii-=3) > 0) {
    pieces.splice(ii, 0, delimiter)
  }
  
  if (typeof custom === 'function') {
    return custom({
      sign,
      float: value, 
      value: pieces.join('') 
    })
  }
  
  return append
    ? pieces.join('') + sign
    : sign + pieces.join('')
}

// create currency converters with the correct formatting options
const formatDollar = makeMoneyFormatter()
const formatPound = makeMoneyFormatter({ 
  sign: '£',
  precision: 0
})
const formatEuro = makeMoneyFormatter({
  sign: '€',
  delimiter: '.',
  decimal: ',',
  append: true
})

const customFormat = makeMoneyFormatter({
  round: false,
  custom: ({ value, float, sign }) => `SALE:$${value}USD`
})

console.log(
  formatPound(1000),
  formatDollar(10000.0066),
  formatEuro(100000.001),
  customFormat(999999.555)
)

synthet1c
источник
Отличный фрагмент кода, спасибо. Однако будьте осторожны, так как он не будет работать в IE, поскольку параметры по умолчанию не поддерживаются, а const и let не поддерживаются в <IE11. Ue это исправить: + moneyFormat: function (price, sign) {+ if (! Sign) sign = '$'; + штук = parseFloat (цена). Исправлено (2). Сплит ('') + вар II = штук. длина - 3
Чарли Далсасс
Не беспокойся @CharlieDalsass. Я бы порекомендовал использовать babel для компиляции до ES5 для производственного кода.
synthet1c
Но как сделать евро валюту? 1.000,00 евро?
@YumYumYum Я добавил полный пример с большим количеством опций форматирования, чтобы обеспечить большую гибкость.
synthet1c
18

Ответ Патрика Дежарденса выглядит неплохо, но я предпочитаю свой простой 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];
}
Тим Сэйлор
источник
Мне нужно было что-то, чтобы работать как в браузере, так и в старой версии Node. Это сработало отлично. Спасибо
n8jadams
17

Основная часть вставляет разделители тысяч, что можно сделать так:

<script type="text/javascript">
function ins1000Sep(val){
  val = val.split(".");
  val[0] = val[0].split("").reverse().join("");
  val[0] = val[0].replace(/(\d{3})/g,"$1,");
  val[0] = val[0].split("").reverse().join("");
  val[0] = val[0].indexOf(",")==0?val[0].substring(1):val[0];
  return val.join(".");
}
function rem1000Sep(val){
  return val.replace(/,/g,"");
}
function formatNum(val){
  val = Math.round(val*100)/100;
  val = (""+val).indexOf(".")>-1 ? val + "00" : val + ".00";
  var dec = val.indexOf(".");
  return dec == val.length-3 || dec == 0 ? val : val.substring(0,dec+3);
}
</script>

<button onclick="alert(ins1000Sep(formatNum(12313231)));">
оборота
источник
Я получаю неправильный вывод числа при вводе отрицательных значений в ins1000Sep ().
Питер
16

Есть встроенный function toFixed вjavascript

var num = new Number(349);
document.write("$" + num.toFixed(2));
Ворота
источник
Этот ответ выглядит излишним. Ответ Давки уже наделен ментиномtoFixed()
Ян Данн
3
toFixed()является функцией Numberобъекта и не будет работать, var numесли бы он был String, поэтому мне помог дополнительный контекст.
Тимборден
15
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 .

Билл Ящерица
источник
Маленький и простой. Спасибо.
Коннор Симпсон
1
простой, но без запятой на 1000
арон
15

Я предлагаю класс NumberFormat из API визуализации Google .

Вы можете сделать что-то вроде этого:

var formatter = new google.visualization.NumberFormat({
    prefix: '$',
    pattern: '#,###,###.##'
});

formatter.formatValue(1000000); // $ 1,000,000

Я надеюсь, что это помогает.

оборота juanchopx2
источник
14

Это может быть немного поздно, но вот метод, который я только что разработал для коллеги, чтобы добавить функцию с поддержкой локали .toCurrencyString()ко всем числам. Интернализация предназначена только для группировки чисел, а НЕ для знака валюты - если вы выводите доллары, используйте их в том "$"виде, в каком они есть, потому что $123 4567в Японии или Китае такое же количество долларов США, как $1,234,567и в США. Если вы выводите евро / и т. Д., Измените знак валюты с "$".

Объявите об этом где-нибудь в вашем HEAD или там, где это необходимо, непосредственно перед тем, как вам нужно его использовать:

  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"
Jay Dansand
источник
12

Как обычно, есть несколько способов сделать одно и то же, но я бы не стал использовать их, 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);
    }
}

отредактировано 2010/08/30: добавлена ​​опция для установки количества десятичных цифр. отредактировано 2011/08/23: добавлена ​​опция для установки числа десятичных цифр на ноль.

Миллер Медейрос
источник
Смысл toLocaleString в том, что он настраивается с настройками пользователя.
Джозеф Леннокс
11

Вот некоторые решения, все из которых проходят тестовый набор, тестовый набор и тест включены, если вы хотите скопировать и вставить для тестирования, попробуйте This Gist .

Метод 0 (RegExp)

Основываясь на 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('.');
    }
}

Способ 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, 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();
Steely Wing
источник
Улучшено по сравнению с вашим способом ; var a = Math.round (wholeNumber / 10) * 10 / множитель; if (String (a) .indexOf ('.') <1) {a + = '.00'; } a = String (a) .split ('.'), не используйте toFixed, потому что он глючит.
ви
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 все эти десятичные значения должны быть 0,84, а не 0,83
VE
10

Простая опция для правильного размещения запятой путем обращения строки вначале и базового регулярного выражения.

String.prototype.reverse = function() {
    return this.split('').reverse().join('');
};

Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) {       
     // format decimal or round to nearest integer
     var n = this.toFixed( round_decimal ? 0 : 2 );

     // convert to a string, add commas every 3 digits from left to right 
     // by reversing string
     return (n + '').reverse().replace( /(\d{3})(?=\d)/g, '$1,' ).reverse();
};
трой
источник
10

Я нашел это из: accounting.js . Это очень легко и идеально подходит для моих нужд.

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

// European formatting (custom symbol and separators), can also use options object as second parameter:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99

// Negative values can be formatted nicely:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000

// Simple `format` string allows control of symbol position (%v = value, %s = symbol):
accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP

// Euro currency symbol to the right
accounting.formatMoney(5318008, {symbol: "€", precision: 2, thousand: ".", decimal : ",", format: "%v%s"}); // 1.008,00€ 

Faysal Haque
источник
$('#price').val( accounting.formatMoney(OOA, { symbol: "€", precision: 2,thousand: ".", decimal :",",format: "%v%s" } ) );- показать 1.000,00 E