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

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

"$ 2,500.00"

Как лучше всего это сделать?

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

Daniel Magliola 29.09.2008 19:24

Пожалуйста, всем, кто будет читать это в будущем, используйте нет для хранения валюты с плавающей запятой. Вы потеряете точность и данные. Вы должны сохранить его как целое число центов (или пенсов и т. д.), А затем преобразовать перед выводом.

Philip Whitehouse 04.03.2012 17:35

@PhilipWhitehouse, что может привести к потере данных с менее чем двумя знаками после запятой?

Kyle 22.05.2012 00:23

@ user1308743 Float не хранит десятичные разряды. Он хранит числа, используя значение, базу и смещение. 0,01 на самом деле не представляется. См .: en.wikipedia.org/wiki/Floating_point#Accuracy_problems

Philip Whitehouse 10.06.2012 15:11

@ user1308743: Представьте, что вы представляете очень большое число (допустим, вы счастливчик, и это баланс вашего банковского счета). Вы действительно хотите потерять деньги из-за недостатка точности?

ereOn 06.08.2012 13:14

@PhilipWhitehouse прав: хранить деньги как поплавок - определенно плохая идея. Однако хранение денег в виде центов работает только тогда, когда вы имеете дело только с целыми центами, что недостаточно точно для многих операций. Недавно мы перешли на хранение валюты в виде «большого десятичного знака» с 7 знаками после запятой. Вы можете использовать метод Javascript toFixed (7) для имитации этого, хотя при необходимости он возвращает строку. Однако это означает, что вы можете работать со знакомыми форматами $ xx.xx, не конвертируя обратно центов.

Ben Hull 16.05.2013 03:52

Так почему никто не предложил следующее? (2500) .toLocaleString ("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2}) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Nick Grealy 25.09.2013 05:41

@NickG Полагаю, из-за того, что поддержка устаревших браузеров довольно дрянная. Но в идеальном мире (где у всех есть современные браузеры) это было бы лучшим решением.

Ben 19.08.2014 17:27

вы можете использовать эту javascript-библиотеку Numeral.js для преобразования ваших чисел в доллары. (numeraljs.com) для справки.

Aarthi 11.09.2014 14:30

Не забудьте, что в скобках ($#,##0.00) на английском языке указаны отрицательные значения валюты.

einstein 26.10.2014 04:45

@NickG Я был в восторге от вашего решения, но не работает на IPad, Android и IE7, работает только в Mozilla и Opera из того, что я проверял

Testo Testini 06.02.2015 00:14

@TestoTestini - спасибо, кстати, Mozilla задокументировала таблицу совместимости для браузеров developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Nick Grealy 06.02.2015 01:47

@TestoTestini (a) NickG См. Этот jsFiddle: jsfiddle.net/v7tws309

cssyphus 07.02.2015 07:14

@RoccoTheTaco: Не уверен, что вы говорите. Другой вопрос старше, имеет больше голосов, больше ответов и ответ с большим количеством голосов. (Субъективное) среднее качество ответов аналогично. Если честно, их лучше объединить.

Bergi 08.05.2015 01:51

Нет ничего плохого в том, чтобы быть универсальным, не так ли?

Bergi 10.05.2015 16:18

@PhilipWhitehouse Хотя хранить его как float нехорошо, я считаю, что валюту отображать в js в виде float вполне нормально. Пока вы не выполняете над ним вычисления, например, суммируете столбец и т. д. Я сохраняю и обрабатываю значение в десятичном формате C# и просто отправляю его в js как float, где оно отображается. Если вы наберете в консоли «.1» или «.61», он будет отображаться нормально, хотя «1.03– .42» - нет. Элементарный тест: для (var i = -200; i <= 200; ++ i) console.info (i / 100); Я также отправляю отредактированные числа с плавающей запятой обратно на свой веб-сервер, что должно быть в порядке: JSON.stringify (.1): "0.1".

Curtis Yallop 08.06.2015 21:03

Если вы читаете это в> = 2017, это должно быть полезно: связь

Amir 21.02.2017 20:51

@ Амир, это уже в мой ответ

aross 05.07.2017 11:03

@CurtisYallop, только если отображается значение без валюты, потому что english.stackexchange.com/a/11327/118419

LogicDaemon 14.03.2019 23:21

@NickGrealy Святое дерьмо. Чувак, я не знал этой функции. Я всегда писал свои кастомные функции. Cooooool. Спасибо

Mike Aron 29.11.2020 01:25

Спасибо, @MikeAron, в любое время. Поставьте +1, чтобы помочь другим - stackoverflow.com/a/18994850/782034

Nick Grealy 29.11.2020 15:23

Для конвертации INR используйте (4027775861.4) .toLocaleString ('en-IN', {maximumFractionDigits: 2, style: 'currency', currency: 'INR'}); // возвращает -> "₹ 4,02,77,75,861,40"

Rajeev Jayaswal 17.12.2020 17:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2 021
22
2 104 222
67
Перейти к ответу Данный вопрос помечен как решенный

Ответы 67

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

<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,",");
  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 ().

Peter 11.08.2015 10:32

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, "" + 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, "" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
  } catch (e) {
    console.info(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>

Если вы всегда хотите округлить до 5 и меньше 5, вы не можете полагаться на toFixed () из-за стандартных проблем, связанных с представлением чисел с плавающей запятой в двоичном формате. Например, попробуйте (1.005).toFixed(2).

Ryan 19.10.2010 23:20

в первую очередь отличный, лаконичный код. однако, если вы американец, вам следует изменить значения по умолчанию для d и t на . и , соответственно, чтобы вам не приходилось указывать их каждый раз. Кроме того, я рекомендую изменить начало инструкции return следующим образом: return s + '$' + [rest], иначе вы не получите знак доллара.

Jason 01.02.2011 02:58

Спасибо, это здорово. Изменен для работы со строками, вводимыми пользователем (сначала преобразует строку в числа, если они вводят 1500 долларов). String.prototype.formatMoney = function (c, d, t) {var n_dirty = this, n = n_dirty.replace (/ [^ \ d.] / G, ''), c = isNaN (c = Math.abs ( в))? 2: c, d = d == undefined? "." : d, t = t == undefined? ",": t, s = n <0? "-": "", i = parseInt (n = Math.abs (+ n || 0) .toFixed (c)) + "", j = (j = i.length)> 3? j% 3: 0; return s + (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): ""); };

Zhenya 20.08.2011 04:58

Вы можете использовать «10» в качестве основания в parseInt. В противном случае для любого числа, начинающегося с «0», будет использоваться восьмеричная нумерация.

sohtimsso1970 15.11.2011 20:01

Значение по умолчанию, равное 0, остается восьмеричным, но не рекомендуется. Но да, вы можете добавить это, если хотите.

Patrick Desjardins 15.11.2011 22:10

Не уверен, почему люди считают этот код красивым. Это не поддается расшифровке. Вроде неплохо работает, но некрасиво.

usr 24.10.2012 20:28

Копируется ли эта функция formatMoney из какого-нибудь миниатюрного кода JavaScript? А оригинал нельзя выложить? Что обозначают переменные c, d, i, j, n, s и t? Судя по количеству голосов и комментариев к этому сообщению, я могу предположить, что этот код был скопирован и вставлен на производственные веб-сайты повсюду ... Удачи в поддержании кода, если когда-нибудь в нем будет ошибка!

zuallauz 18.12.2012 00:41

Это решение работает не очень хорошо. 1.155.formatMoney (2, '.', ',) ===' 1.16 ', но 2.155.formatMoney (2,'. ',', ') ===' 2.15 '

Nick Colgan 21.12.2012 02:52

"поэзия"? Больше похоже на безвестность. Это не кодовый гольф; используйте небольшое пустое пространство. Правильные имена var тоже не повредят.

keithjgrant 30.12.2012 18:07

Не говоря уже о том, что используется d == undefined, тогда как typeof(d) === 'undefined' должен быть на месте.

trejder 27.08.2013 12:04

@trejder почему так? Если у вас есть глупые программисты, которые определяют undefined как переменную с содержимым, вам хорошо. Кстати, вам не нужно (и поэтому не следует) использовать круглые скобки для typeof.

Micaël Félix 25.09.2013 17:35

@MykaEyl Прочтите об основах JS, прежде чем говорить что-то, что ... немного неправильно. Переменная с именем undefined определяется автор: JS, а не некоторыми глупыми программистами, и вы должен используете круглые скобки для typeof, потому что без нее вы будете сравнивать ее с этой переменной с именем undefined. Я не излагаю здесь свои мысли, я просто скопировал то, что выражено во многих ответах SO и во многих источниках. Сейчас нет времени искать пример, но вы обязательно его найдете, если погуглите еще немного.

trejder 25.09.2013 19:23

@trejder Скобки с typeof абсолютно не влияют на то, как конструкция анализирует эту форму - typeof имеет тот же приоритет, что и унарный оператор. Также в предыдущем комментарии говорилось, что это безопасно, чтобы полагаться на то, что undefined оценивается как (void 0), пока «глупый программист» не вводит теневую локальную переменную undefined и не повторно связывает window.undefined. (Я считаю, что нарушителем является этот код, а не код, использующий undefined.)

user2864740 18.11.2013 23:17

@ user2864740 Если подумать, я согласен (конечно!) не использовать круглые скобки (я должен был быть слепым, когда впервые читал комментарий Мика Эйл!:]). Но я не согласен со второй частью. Причина, по которой вы должны использовать typeof d === 'undefined' вместо d === undefined, заключается в том, что при первом подходе вам не нужно заботиться о глупые разработчики. Поскольку мир переполнен глупые разработчики, нам нужно тратить время на собственное кодирование, а не на то, чтобы предвидеть возможные попытки глупые разработчики испортить наш код, верно? :]

trejder 18.11.2013 23:49

@trejder Я столкнулся с этой проблемой с никогда. Любая среда, в которой undefined был переопределен на значение, отличное от (void 0), является средой, которую я буду поддерживать нет. (В Python 2.x True и False были просто переменными - например, True,False=False,True допустимо - но никогда не было никаких попыток найти «безопасный» метод.)

user2864740 18.11.2013 23:56

@trejder Поскольку мир переполнен глупыми разработчиками, нам нужно тратить время на собственное кодирование, а не на то, чтобы предвидеть возможные попытки глупых разработчиков испортить наш код, верно? => Следуя этой мысли, разве typeof(d) === 'undefined' не является попыткой предвидение возможных попыток глупых разработчиков испортить наш код? Если бы кто-то действительно переопределил undefined, я бы не стал доверять им, чтобы они не сделали что-то еще, чтобы взломать ваш код.

Bob 17.01.2014 07:19

@RobQuist Он почти наверняка имел в виду перевернутый по сравнению с тем, что находится в коде, а не как приглашение к повторной войне за независимость.

McGuireV10 21.05.2014 19:57

Как отмечали предыдущие комментаторы, это не только сбивает с толку, но и неправильно. Это дает 49.65.formatMoney (1, '.', ',') => 49.6

hlascelles 09.12.2014 15:13

Я использовал это, но получил ошибку, поэтому добавляю var myMoney = Number (myMoney) .toFixed (2); добавление Number () сработало.

CookieCoder 11.12.2014 20:03

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

Deji 26.11.2015 13:33

@Deji, к черту стандарты стиля кодирования, именование вещей, структурирование кода, комментирование и аннотирование.

aross 16.12.2015 11:56

@aross Связан ли этот вопрос со стандартами стиля кодирования, «именованием вещей», структурированием кода, комментированием и аннотацией? Вы неопределенно упоминаете какую-либо из этих концепций, приводя какие-либо причины, по которым приведенный выше конкретный код не является подходящим ответом? Нет...

Deji 16.12.2015 16:30

@Deji Значит, вы даже считаете обфусцированный код хорошим ответом?

aross 16.12.2015 18:05

@aross Зависит от вопроса. Я думаю, что вы здесь не понимаете - комментарии предназначены не для оценки качества кода, а для оценки качества ОТВЕТА. Мне действительно не нужно объяснять, как обычно оцениваются ответы на вопросы по качеству ...

Deji 16.12.2015 18:08

К счастью, это вики сообщества, так что любой из вас, жалующийся на формат / удобочитаемость кода, может просто исправить это самостоятельно.

Kevin B 16.12.2015 19:20

Эта функция неверна:> (2030) .formatMoney (0, '.', ''); <"2 03 0"

Anton P Robul 18.03.2016 22:24

Странный код, на мой взгляд, напр. value дважды повторно назначается внутри функции, что очень затрудняет отладку. При decimalPlaces = 0 значение неявно округляется на «toFixed», которое в моем случае не имеет отступа.

wosis 28.04.2016 11:41
Любой дурак может написать код, понятный компьютеру. Хорошие программисты пишут код, понятный людям
Liam 07.06.2016 15:32

Как такая ужасная практика получила 1K + голосов? Не говоря уже о том, что он был написан предварительно.

user1596138 31.08.2016 00:52

Поскольку мне не нравится код, который я не могу прочитать, я переписал его, чтобы он был удобнее для разработчиков: syntaxwarriors.com/p/18/Format-currency-in-Javascript Практически то же самое, но читабельный.

JensB 20.12.2016 13:12

Неминифицированная версия: josscrowcroft.com/2011/code/… (см. «Формат денег JavaScript»).

Victor Dombrovsky 30.12.2016 21:48

Прототип toLocaleString() делает то же самое с меньшим количеством кода. и более надежен. Ответил здесь

Mark Carpenter Jr 27.06.2017 17:22

Я лично считаю это решение мусором. Вы не используете разумные имена переменных, вы изменяете prototype встроенного модуля с помощью свойства перечислимый, и ваш код даже не имеет смысла, даже если он работает.

Patrick Roberts 18.07.2017 07:12

Этот ответ сейчас несколько устарел. См. Ответ о формате международного номера ниже.

Captain Hypertext 10.11.2017 18:49

Код на этом сайте должен быть удобочитаемым для людей, а не для веб-браузеров.

Bacon Brad 22.06.2018 22:12

Если дата может быть нулевой, тогда вам нужно вызвать функцию следующим образом: formatMoney(someDate, 2) вместо someDate.formatMoney(2), иначе вы получите «Uncaught TypeError: Cannot read property 'value' of null», когда это так.

Robin Wilson 15.12.2018 22:03

Я удивлен, что никто не упомянул, что линия j = (j = i.length) > 3 ? j % 3 : 0; вызывает j до того, как она будет определена.

Caio Mar 31.05.2019 02:11

Этому коду сложно следовать. По крайней мере, дайте несколько имен параметрам.

Jakub Keller 08.06.2019 14:59

ПРЕДУПРЕЖДЕНИЕ! Код, отличный от ES6, не работает по состоянию на 31.10.2019, я удивлен, что он получил столько голосов! Исправьте следующие простые случаи: 100000 (результат 100000,00) и 1000000 (результат 1,000000,00)

ryanm 31.10.2019 17:12

Код не ES6 не работает, что-то не так с используемым regExpression, я не обновлял свой reg ex годами, поэтому, к сожалению, я не могу его исправить

beliha 28.11.2019 09:34

Очиститель не ES6: функция formatMoney (количество, десятичное число, десятичное число, тысячи) {decimalCount = Math.abs (decimalCount); decimalCount = isNaN (decimalCount)? 2: decimalCount; var negativeSign = количество <0? "-": ""; var i = parseInt (amount = Math.abs (Number (amount) || 0) .toFixed (decimalCount)). toString (); var j = (длина i> 3)? i.length% 3: 0; return negativeSign + (j? i.substr (0, j) +ousands: '') + i.substr (j) .replace (/ (\ d {3}) (? = \ d) / g, "$ 1" + тысяч) + (decimalCount? decimal + Math.abs (количество - i) .toFixed (decimalCount) .slice (2): ""); }

beliha 07.03.2020 11:36

есть ли способ опровергнуть этот ответ. это больше не актуально.

user1556937 26.06.2020 00:19

Все просто проголосуют против этого ответа, чтобы правильный ответ был более заметным.

TheGeekZn 09.11.2020 11:57

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

Martin Braun 24.11.2020 04:55

Неверный код "Пользовательской функции". Например, при запуске фрагмента кода 1234567.12 возвращается как 1,234567.12, это просто неправильно.

Mike Jarema 18.02.2021 00:38

Взгляните на объект JavaScript Число и посмотрите, может ли он вам помочь.

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

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

Пример:

Number((someNumber).toFixed(1)).toLocaleString()

Спасибо! На основе этой идеи я смог сделать достаточно короткий и простой! (и с локализацией) Отлично.

Daniel Magliola 29.09.2008 19:25

На самом деле можно. то есть для долларов: '$' + (значение + 0,001) .toLocaleString (). slice (0, -1)

Zaptree 18.11.2013 07:33

Похоже, это было бы здорово, но на данный момент поддержка браузеров невелика.

acorncom 06.12.2013 04:38

Safari определенно реализует функции toLocale иначе. Форматы даты локали также производят другой вывод, чем любой другой основной браузер.

Neil Monroe 26.06.2014 20:18

@acorncom Почему вы говорите, что браузер "почти не поддерживает"? Объект Number существует с Javascript 1.1. Предоставьте ссылку, подтверждающую вашу претензию.

Doug S 31.08.2015 06:43

Следует позаботиться о том, чтобы существовала старая версия toLocaleString, использующая системный языковой стандарт, и новая (несовместимая) версия, исходящая от ECMAScript Intl API. Объясняется здесь. Этот ответ, похоже, предназначен для старой версии.

aross 14.09.2017 13:09

Не уверен, почему за это так проголосовали, но это не соответствует тому, о чем просит OP. Например, 10000 превратится в "10,000", а не в "10,000.00", что является желаемым поведением для форматирования валюты.

Burak 07.06.2018 17:20

По поводу комментария @Burak. Я не думаю, что это так. Для меня код "var currency =" $ "+ Number (someNumber.toFixed (2)). ToLocaleString ()" превращается в var someNumber = 2345667.7899; на $ 2 345 667,79, что мне и нужно.

Alexander 10.06.2018 04:48

@Alexander, а что, если someNumber - это «234567» или «234567,8»? Тогда у вас будет ноль или один десятичный знак вместо двух, что не то, чего хочет OP, и, как правило, кажется нежелательным и для форматирования валюты.

Burak 18.06.2018 16:59

Да вы правы. Сейчас я использую прототип Number.prototype.formatMoney, который указан ниже.

Alexander 20.06.2018 13:43

лучший ответ на сегодняшний день

oldboy 12.08.2019 12:06

Number () является обязательным, если переменная является строкой или любым другим типом. Это мне очень помогло! спасибо, что поделились этим.

acido 08.11.2019 21:22

Я согласен с @Burak, почему это пока лучший ответ .. кто-нибудь пробовал? он не дает ожидаемого результата

Cegone 16.06.2020 17:03

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.

Маленький и простой. Спасибо.

Connor Simpson 28.07.2016 16:19

просто, но без запятой для 1000

aron 19.03.2018 20:24

Кодовая база 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 на "."

Слишком долго, и мне придется включить YUI

Daniel Magliola 29.09.2008 19:25

Моя первая реакция была "лол - слишком долго, YUI отстой" ... но после пересмотра, это неплохой код, просто очень ... полный. Он проверяет, действительно ли аргумент является числом (не выполняется другими плакатами, и это единственная часть, которая требует библиотеки YUI). Он округляет (не для всех плакатов). Он имеет настраиваемый разделитель, префикс и суффикс. Наконец, код комментируется и не использует регулярных выражений и сложных однострочных выражений. Итак ... я даю вам +1, чтобы компенсировать другим -1 ... этот код неплох - его можно адаптировать, даже если не использовать YUI.

Nick Perkins 15.11.2011 23:13

В YUI они, должно быть, больны, не могут поверить, что написали такой кусок кода.

Marco Demaio 09.02.2012 15:47
Ответ принят как подходящий

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

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 только для этого :-)) Я уже знаю, что должен обнаружить "." вместо того, чтобы просто использовать его как десятичный разделитель ...

Обратите внимание, что ваша версия неправильно округляет до двух десятичных цифр. Например, 3,706 будет отформатировано как «3,70 фунта стерлингов», а не как «3,71 фунта стерлингов», как должно быть.

Ates Goral 01.10.2008 03:33

Да, в моем конкретном случае это нормально, поскольку суммы, с которыми я работаю, уже имеют не более 2 цифр. Причина, по которой мне нужно исправить до 2 десятичных знаков, - это суммы без десятичных знаков или только с 1.

Daniel Magliola 02.10.2008 23:12

Минималистичный подход, полностью отвечающий первоначальным требованиям:

function formatMoney(n) {
    return "$ " + (Math.round(n * 100) / 100).toLocaleString();
}

@ Даниэль Маглиола: Вы правы, вышесказанное было поспешной и неполной реализацией. Вот исправленная реализация:

function formatMoney(n) {
    return "$ " + n.toLocaleString().split(".")[0] + "."
        + n.toFixed(2).split(".")[1];
}

Простите, нет. Это приведет к удалению лишних десятичных знаков, но не к двум десятичным разрядам. «25» будет «25 долларов США» с вашим кодом, а не «25 долларов США».

Daniel Magliola 29.09.2008 23:22

Все равно ошибаюсь! Вы используете toLocaleString, который может сделать десятичный разделитель "," вместо ".", И предполагается, что это "."

Daniel Magliola 02.10.2008 23:13

Это был «минималистичный» подход для удовлетворения первоначальных нечетких требований, в которых в качестве примера было указано «2500 долларов США».

Ates Goral 03.10.2008 18:49

Есть 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+'');
        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'

Это только одна правильная функция:> number_format (2030, 0, '.', '') <'2 030' Отлично! Спасибо

Anton P Robul 18.03.2016 22:29

Ниже приведен код Патрик Дежарден (псевдоним Даок) с небольшими добавленными комментариями и небольшими изменениями:

/* 
decimal_sep: character used as decimal separator, 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 [https://stackoverflow.com/questions/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, "" + 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

Вы можете использовать «10» в качестве основания в parseInt. В противном случае для любого числа, начинающегося с «0», будет использоваться восьмеричная нумерация.

sohtimsso1970 15.11.2011 20:01

@ sohtimsso1970: извините за поздний ответ, но не могли бы вы объяснить еще кое-что? Я не понимаю, где число может интерпретироваться как восьмеричное. parseInt вызывается по абсолютному значению целой части числа. Часть INTEGER не может начинаться с ZERO, если только это не просто ZERO! А parseInt(0) === 0 либо восьмеричный, либо десятичный.

Marco Demaio 09.02.2012 16:20

попробуйте, например: parseInt ("016") ... возвращает 14, поскольку parseInt предполагает, что он закодирован в восьмеричной системе, когда строка начинается с нуля.

Tracker1 20.03.2012 04:02

@ Tracker1: Я понял, что число, начинающееся с 0, parseInt считает восьмеричным. Но в этом коде НЕВОЗМОЖНО для parseInt получить 016 в качестве ввода (или любое другое восьмеричное форматированное значение), потому что аргумент, переданный parseInt, первым обрабатывается функцией Math.abs. Таким образом, parseInt не сможет получить число, начинающееся с нуля, если только это не просто ноль или 0.nn (где nn - десятичные числа). Но строки 0 и 0.nn будут преобразованы parseInt в простой ZERO, как и предполагалось.

Marco Demaio 20.03.2012 18:57

Эта функция неверна:> (2030) .toMoney (0, '.', ''); <"2 03 0"

Anton P Robul 18.03.2016 22:26

@AntonPRobul это неправда, вы можете проверить это с помощью ссылки JS FIddle, добавленной в ответ, (2030).toMoney(0, '.', ' '); дает следующее: "2 030", что является ожидаемым результатом, поскольку вы указываете функции использовать один пробел в качестве разделителя тысяч.

Marco Demaio 31.01.2021 01:58

function getMoney(A){
    var a = new Number(A);
    var b = a.toFixed(2); //get 12345678.90
    a = parseInt(a); // get 12345678
    b = (b-a).toPrecision(2); //get 0.90
    b = parseFloat(b).toFixed(2); //in case we get 0.0, we pad it out to 0.00
    a = a.toLocaleString();//put in commas - IE also puts in .00, so we'll get 12,345,678.00
    //if IE (our number ends in .00)
    if (a < 1 && a.lastIndexOf('.00') == (a.length - 3))
    {
        a=a.substr(0, a.length-3); //delete the .00
    }
    return a+b.substr(1);//remove the 0 from b, then return a + b = 12,345,678.90
}
alert(getMoney(12345678.9));

Это работает в FF и IE

Как обычно, есть несколько способов сделать одно и то же, но я бы не стал использовать 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 [], middle [] and decimal digits []

    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);
    }
}

отредактировано 30.08.2010: добавлена ​​возможность установки количества десятичных цифр.отредактировано 2011/08/23: добавлена ​​возможность установить количество десятичных цифр равным нулю.

Смысл toLocaleString в том, что он настраивается в соответствии с настройками пользователя.

Joseph Lennox 15.08.2013 06:44

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

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) // ",664,544.23"
formatDollar(45) // ".00"
formatDollar(123) // "3.00"
formatDollar(7824) // ",824.00"
formatDollar(1) // ".00"

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

поэзия. блестящий. Вы пробовали reduceRight () developer.mozilla.org/en/JavaScript/Reference/Global_Objects‌ /…, который должен устранить reverse ()?

Steve 21.12.2011 01:50

@Steve - Вы правы, но вам нужно сделать что-то вроде i = orig.length - i - 1 в обратном вызове. Тем не менее, на один обход массива меньше.

Wayne 21.12.2011 02:29

Не о совместимости: метод reduce был представлен в Ecmascript 1.8 и не поддерживается в Internet Explorer 8 и ниже.

Blaise 10.05.2012 16:07

Как сказал @Blaise, этот метод не будет работать в IE 8 или ниже.

rsbarro 01.08.2013 23:46

Да, конечно, правильно. Как отмечено в самом ответе, это просто для развлечения. Кроме того, он должен нормально обрабатывать отрицательные числа.

Wayne 17.09.2013 00:23

Отрицательные числа у меня работали нормально. Что мне нравится в этом, так это то, что кода не так много, и он не зависит от регулярного выражения.

Betty Mock 15.01.2015 03:10

Почему вы просто не сделали (parseInt(p[0])).toLocaleString()?

Chase Sandmann 16.06.2015 23:37

Потому что эта функция может давать разные результаты в разных регионах. Это вполне может быть то, что вы хотите, но это не дает прямого ответа на конкретный вопрос о форматировании. (Также обратите внимание на дату в вопросе / ответах здесь.)

Wayne 17.06.2015 00:07

чтобы правильно обрабатывать отрицательное число, добавьте следующий код перед возвратом num= = "-" ? acc: <br> т.е. функция, переданная в метод уменьшения, будет иметь вид <br> function(acc, num, i, orig) { return num= = "-" ? acc:num + (i && !(i % 3) ? "," : "") + acc; }

Akshay Vijay Jain 07.12.2016 09:27

Но как это сделать в валюте евро?

user285594 06.06.2017 18:40

Пример Патрика Дежардена (бывшего Даока) хорошо мне подошел. Я перенес на coffeescript, если кому интересно.

Number.prototype.toMoney = (decimals = 2, decimal_separator = ".", thousands_separator = ",") ->
    n = this
    c = if isNaN(decimals) then 2 else Math.abs decimals
    sign = if n < 0 then "-" else ""
    i = parseInt(n = Math.abs(n).toFixed(c)) + ''
    j = if (j = i.length) > 3 then j % 3 else 0
    x = if j then i.substr(0, j) + thousands_separator else ''
    y = i.substr(j).replace(/(\d{3})(?=\d)/g, "" + thousands_separator)
    z = if c then decimal_separator + Math.abs(n - i).toFixed(c).slice(2) else ''
    sign + x + y + z

Это может сработать:

function format_currency(v, number_of_decimals, decimal_separator, currency_sign){
  return (isNaN(v)? v : currency_sign + parseInt(v||0).toLocaleString() + decimal_separator + (v*1).toFixed(number_of_decimals).slice(-number_of_decimals));
}

Никаких циклов, никаких регулярных выражений, никаких массивов, никаких экзотических условных выражений.

javascript-number-formatter (ранее в Код Google)

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

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

вот быстрый способ использования regexp и replace.

function formatCurrency( number, dp, ts ) {
  var num = parseFloat( number ); //convert to float
  var pw; //for IE
  dp = parseInt( dp, 10 ); //decimal point
  dp = isNaN( dp ) ? 2 : dp; //default 2 decimal point
  ts = ts || ','; //thousands separator

  return num != number ? 
    false : //return false for NaN
    ( ( 0.9 ).toFixed( 0 ) == '1' ? //for cater IE toFixed bug
        num.toFixed( dp ) : //format to fix n decimal point with round up
        ( Math.round( num * ( pw = Math.pow( 10, dp ) || 1 ) ) / pw ).toFixed( dp ) //for fix ie toFixed bug on round up value like 0.9 in toFixed
    ).replace( /^(-?\d{1,3})((\d{3})*)(\.\d+)?$/, function( all, first, subsequence, dmp, dec ) { //separate string into different parts
      return ( first || '' ) + subsequence.replace( /(\d{3})/g, ts + '' ) + ( dec || '' ); //add thousands seperator and re-join all parts
    } );
}

приведите пример использования этой функции.

jao 16.11.2012 17:30

Использую библиотеку Глобализировать (от Microsoft):

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

Вау, почему за это не проголосовали больше? Большая стандартизированная библиотека для всевозможного форматирования. Стандартные для отрасли параметры форматирования с правильной глобализацией. Отличный ответ !!

pbarranis 10.09.2013 06:11

Это все еще считается альфа-стадией, поэтому используйте осторожно, но отличная находка.

Neil Monroe 26.06.2014 20:23

Больше не в альфа (или бета). Это кажется очень полезным, пока мы ждем, пока Safari не будет соответствовать новому стандарту, а IE <11 умрет.

Guy Schalnat 21.08.2015 21:26

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

... просто не забудьте передать символ валюты, иначе он выйдет из строя в IE7 и IE8, IE9 в любом случае в порядке

vector 08.10.2011 00:51

Похоже, ошибка IE7 / IE8 исправлена.

Mat Schaffer 17.01.2012 23:41

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

farinspace 20.10.2012 02:15

Мне нравится то, что вы можете сделать обратное - передать отформатированную строку валюты и получить числовое значение.

Neil Monroe 26.06.2014 20:25

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

Ted 05.03.2015 12:03

account.js, похоже, не поддерживается в последнее время. Один форк с недавними изменениями - github.com/nashdot/accounting-js

RationalDev likes GoFundMonica 21.04.2016 01:49

Более быстрый способ с регулярным выражением?

Number.prototype.toMonetaryString=function(){var n=this.toFixed(2),m;
// var=this.toFixed(2).replace(/\./,','); for comma separator
// with a space for thousands separator
  while ((m=n.replace(/(\d)(\d\d\d)\b/g,' '))!=n) n=m; 
  return m;
}
String.prototype.fromMonetaryToNumber=function(s){
  return this.replace(/[^\d-]+/g,'')/100;
}   

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

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

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

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

    n=12345678.9;
    alert(n.toCurrencyString());

Это потрясающе! Должны быть лучшие ответы!

Harrison 03.03.2021 01:35

В JavaScript нет эквивалента formatNumber. Вы можете написать это сами или найти библиотеку, которая уже это делает.

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

@ crush это работает, но больше не переносит расчеты в налоговое поле?

Rocco The Taco 17.02.2012 00:49

После того, как вы добавите к нему знак $, это уже не число, а строка.

crush 17.02.2012 00:59

Эта опция не ставит запятую между тысячами. :-(

Simon East 09.10.2019 10:45

Вот лучший форматировщик денег JavaScript, который я видел:

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, "" + 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,',','.'); // ",543.76"

следите за глобальным знаком, i, j

hacklikecrack 20.11.2013 21:33

@hacklikecrack, все переменные локальные; они указаны в заявлении var.

Jonathan M 20.11.2013 21:58

извините, да, хотя вы пересказываете аргументы. Отступ! ;)

hacklikecrack 25.02.2014 20:18

Ужасное использование имен переменных!

Serj Sagan 09.04.2018 21:50

В function есть встроенный javascripttoFixed

var num = new Number(349);
document.write("$" + num.toFixed(2));

Этот ответ выглядит излишним. Ответ Crush уже упоминался toFixed()

Ian Dunn 25.09.2012 21:28

toFixed() является функцией объекта Number и не будет работать на var num, если это был String, поэтому мне помог дополнительный контекст.

timborden 20.11.2012 18:03

Патрик Дежарден 'ответ выглядит хорошо, но я предпочитаю простой 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 13.08.2019 19:48

String.prototype.toPrice = function () {
    var v;
    if (/^\d+(,\d+)$/.test(this))
        v = this.replace(/,/, '.');
    else if (/^\d+((,\d{3})*(\.\d+)?)?$/.test(this))
        v = this.replace(/,/g, "");
    else if (/^\d+((.\d{3})*(,\d+)?)?$/.test(this))
        v = this.replace(/\./g, "").replace(/,/, ".");
    var x = parseFloat(v).toFixed(2).toString().split("."),
    x1 = x[0],
    x2 = ((x.length == 2) ? "." + x[1] : ".00"),
    exp = /^([0-9]+)(\d{3})/;
    while (exp.test(x1))
        x1 = x1.replace(exp, "" + "," + "");
    return x1 + x2;
}

alert("123123".toPrice()); //123,123.00
alert("123123,316".toPrice()); //123,123.32
alert("12,312,313.33213".toPrice()); //12,312,313.33
alert("123.312.321,32132".toPrice()); //123,312,321.32

+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, "" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

Первая переменная выглядит довольно странно, поскольку эти переменные уже объявлены в объявлении функции. Кроме этого, спасибо!

Rich Bradshaw 22.03.2013 20:15

Ты прав. Это ошибка, которую я перенес из оригинала Джонатана М., где все они связаны как одно выражение var. Это должны быть простые задания. Исправление.

XML 18.10.2013 23:27

В этом отношении, я думаю, что это, вероятно, преждевременно оптимизировано и должно быть переработано для удобства чтения. Но моей целью было дополнить код OP, а не принципиально его изменить.

XML 18.10.2013 23:37

Это не так уж и плохо - +n || 0 - единственное, что кажется немного странным (по крайней мере, мне).

Rich Bradshaw 18.10.2013 23:38

this - очень полезное имя переменной. Преобразование его в n, чтобы вы могли сохранить 3 символа во время определения, возможно, было необходимо в эпоху, когда ОЗУ и пропускная способность считались в КБ, но это просто запутывание в эпоху, когда минификатор позаботится обо всем этом, прежде чем он когда-либо попадет в производство. . Остальные умные микрооптимизации по крайней мере спорны.

XML 18.10.2013 23:49

Верно - не поймал.

Rich Bradshaw 19.10.2013 00:45

если кто-то хочет отменить formatMoney обратно, вот код: String.prototype.undoFormatMoney = function () {var tempVals; var val = this; var sign = ((val.split ('$') [0]) == "-")? "-": "", val = val.split ('$') [1]; tempVals = val.split (','); val = 0; var adjPlaces = 1; len1 = (tempVals.length) - 1; for (var i = len1, j = 0; i> = 0; i--, j ++) {если (j> 0) {adjPlaces = j * 1000; } val = val + ((tempVals [i]) * adjPlaces); } знак возврата + "" + val; };

nikhil 17.06.2014 02:11

Coffeescript для популярного ответа Патрика выше:

Number::formatMoney = (decimalPlaces, decimalChar, thousandsChar) ->  
  n = this  
  c = decimalPlaces  
  d = decimalChar  
  t = thousandsChar  
  c = (if isNaN(c = Math.abs(c)) then 2 else c)  
  d = (if d is undefined then "." else d)  
  t = (if t is undefined then "," else t)  
  s = (if n < 0 then "-" else "")  
  i = parseInt(n = Math.abs(+n or 0).toFixed(c)) + ""  
  j = (if (j = i.length) > 3 then j % 3 else 0)  
  s + (if j then i.substr(0, j) + t else "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "" + t) + (if c then d + Math.abs(n - i).toFixed(c).slice(2) else "")  

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

numeral(23456.789).format('$0,0.00'); // = "$23,456.79"

Форк Numbro, кажется, получает больше любви, поскольку Numeral.js кажется заброшенным: github.com/foretagsplatsen/numbro

RationalDev likes GoFundMonica 21.04.2016 01:41

Numeral.js снова активен.

adamwdraper 03.12.2016 00:22

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

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

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

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

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

Вот мой ...

function thousandCommas(num) {
  num = num.toString().split('.');
  var ints = num[0].split('').reverse();
  for (var out=[],len=ints.length,i=0; i < len; i++) {
    if (i > 0 && (i % 3) === 0) out.push(',');
    out.push(ints[i]);
  }
  out = out.reverse() && out.join('');
  if (num.length === 2) out += '.' + num[1];
  return out;
}

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

  • Короткий, быстрый, гибкий, но автономный. Всего 75 строк, включая информацию о лицензии MIT, пустые строки и комментарии.
  • Примите стандартное форматирование чисел, например #, ## 0.00 или с отрицанием -000. ####.
  • Допускается любой формат страны, например # ## 0,00, #, ###. ##, # '###. ## или любой тип символа без нумерации.
  • Принимайте любые числа с группировкой цифр. #, ##, # 0.000 или #, ### 0. ## допустимы.
  • Примите любое избыточное / надежное форматирование. ##, ###, ##. # или 0 #, # 00 #. ### 0 # все в порядке.
  • Автоматическое округление номеров.
  • Простой интерфейс, просто укажите маску и значение следующим образом: format ("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.info("%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;
}

это просто скопировано из поиска Google. Проект не обновлялся с 2011 года.

Luke Page 20.11.2013 12:53

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

(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/

На самом деле я пошел еще дальше: .replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, ",").

kalisjoshua 21.03.2013 06:50

Версия CoffeeScript с регулярным выражением VisioN и kalisjoshua и способом указания десятичного разряда (так что вы можете оставить значение по умолчанию 2 или указать 0 без десятичного числа): Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, ","

Eric Anderson 18.06.2013 19:43

Если мы вызовем toFixed (0), запятые исчезнут, есть идеи, как заставить его работать с this.toFixed(0).replace(/(\d)(?=(\d{3})+\.)/g, ",")?

Abbas 14.08.2013 21:09

@Abbas Да, замените \. на $ (конец строки), то есть this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, ",").

VisioN 15.08.2013 13:26

Привет, @VisioN, не могли бы вы объяснить регулярное выражение и важность «$ 1». Я использовал функцию регулярного выражения, но пропустил $ в «$ 1». Значит, результат оказался неверным. Помогу мне, если сможешь объяснить. TIA.

hanumant 22.10.2013 18:27

@hanumant Обычная грамматика здесь немного сложна, поэтому я предлагаю вам сначала прочитать руководства по регулярным выражениям (например, на MDN). Идея заключается в замене совпавших разделов первым совпадением и запятой, то есть ,. Сопоставление выполняется с помощью опережающий подход. Вы можете прочитать это выражение как "сопоставить число, если за ним следует последовательность из трех наборов чисел (один или несколько) и точка".

VisioN 22.10.2013 19:08

@VisioN в случае значений по бразильским стандартам (1,222,333,44 реалов), получающих (122233344). Как это сделать? Я безуспешно пробовал некоторые изменения в скрипке. Не могли бы вы мне помочь? (или даже добавьте формат 3 в свой пример, если особо не о чем просить). Я знаю, что принятый ответ покрывает это, но и ваш тоже отлично

Michel Ayres 17.03.2014 16:15

@Michel Вот супер-расширенная версия, которая поддерживает разные типы разделителей: jsfiddle.net/hAfMM/610.

VisioN 17.03.2014 16:47

@VisioN: Ваше короткое решение не работает для длинных номеров. Необходимо заменить \. на a \ b (от слова boudarie), как я предложил 4 января 2012 года (см. ниже).

Julien de Prabère 25.03.2014 14:38

@ JuliendePrabère Приведите пример длинного числа, которое не работает при таком подходе.

VisioN 25.03.2014 14:53

@ Gyrocode.com Почему подход $& вам не подошел?

VisioN 16.06.2015 11:15

Дополнительная супер расширенная версия: jsfiddle.net/hAfMM/2269 Интегрирует символ валюты

Pier-Luc Gendreau 16.06.2015 23:24

Почему это не лучший ответ? Он рассмотрел все возможные варианты

Clain Dsilva 12.09.2015 14:54

хорошо, классный код, к сожалению, я многое не понимаю, но это было очень полезно, спасибо

Andres Felipe 11.12.2015 22:07

@ 1111161171159459134 Это всего лишь короткая и быстрая альтернатива Math.floor(n). Если вы хотите сделать его совместимым с JSHint, замените этот бит соответствующим образом.

VisioN 18.06.2016 23:18

Отличный код. Можно ли сделать обратное, например неформатирование (от 12.345.678,90 до 12345678.9), аналогично любому денежному формату с обычным числом @VisioN

Mohammed Farooq 20.09.2016 10:44

@MohammedFarooq Конечно, так просто: jsfiddle.net/hAfMM/3934.

VisioN 21.09.2016 12:03

@ VisioN - Спасибо, но мне не нужно передавать (запятую и точку) в качестве параметра. Мне нужно вернуть число, если я прохожу (от 12,345,678,90 до 12345678,9) или (от 12,345,678,90 до 12345678,9). E В другом евро или стандартном формате на обычное число

Mohammed Farooq 21.09.2016 12:18

@MohammedFarooq Чтобы это работало, скрипт должен знать, в каком стиле отформатирован ваш номер. Он не может автоматически определять, используется ли точка или запятая в качестве разделителя для разделов или десятичной части. В противном случае вам придется использовать строгий числовой формат, чтобы синтаксический анализатор мог угадать, какой символ от какой части разделяет.

VisioN 21.09.2016 13:47

Как мне отформатировать номер 12514652? Я не могу называть 12514652.format() рубином ... так?

Matrix 22.09.2016 01:45

Спасибо за Ваш ответ. Но у меня есть вопрос: как убрать e + из числа? например, 1000000000000000000000 теперь форматируется как: $ 1e + 21, но я бы хотел, чтобы это было так: $ 1,000,000,000,000,000,000,000.00

Besat 20.10.2016 16:49

@Besat Это сложный вопрос, но мы можем использовать хороший обходной путь с помощью специального метода Number.prototype.toFixed, который может неявно преобразовывать числа в экспоненциальной нотации в их полноразмерное строковое представление. См. Решение здесь: jsfiddle.net/hAfMM/4027.

VisioN 20.10.2016 17:39

Чудесно! Спасибо!

Besat 20.10.2016 17:54

как сделать пример arr [i] .price, отформатированный под это? этот код отлично работает! @Зрение

Faisal 04.11.2016 07:24

@aross К сожалению, Intl API по-прежнему недоступно во многих широко используемых браузерах, и это решение будет иметь смысл, когда требования совместимости включают IE9, IE10, Safari 9 и т. д.

VisioN 04.01.2017 14:10

@aross Часто включение 2-3 строк кода быстрее и проще, чем встраивание библиотеки объемом 50+ КБ, чтобы получить тот же результат. Это зависит от того, что вы на самом деле делаете. Я до сих пор использую этот код в своих проектах, когда мне просто нужно отформатировать число в простом формате.

VisioN 04.01.2017 14:18

@aross Мой опыт говорит об обратном: этого кода хватает в 90% случаев. Я не знаю, что такое группировка индейских цифр, но уверен, что это решение можно легко настроить под нее. Поймите меня правильно, я не говорю, что этот ответ является лучшим на сегодняшний день в 2017 году, но я вполне уверен, что разработчики все равно найдут его полезным.

VisioN 04.01.2017 15:06

VisioN, вы правы - я выбираю первое из ваших коротких решений, которое, кстати, является великолепным регулярным выражением! Спасибо, что поделились, у меня появился нейрон.

Gerard ONeill 27.04.2017 02:25

Моя версия TS, которая работает во многих случаях: export const formatNumberToUSFormat = (numberToFormat: number | string) => { const stringNumber = numberToFormat.toString() return stringNumber.match(/\./g) ? stringNumber.replace(/\d(?=(\d{3})+\.)/g, '$&,') : stringNumber.replace(/\d(?=(\d{3})+$)/g, '$&,') }

Avernikoz 12.10.2018 19:30

Это отличное решение! но я пробовал использовать его для числа, начинающегося с 0, например, (012345).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'). Он возвращает «5 349,00» вместо «12 345,00»

olaoluwa_98 12.05.2020 15:57

@ olaoluwa_98 Числа, начинающиеся с нуля, считаются восьмеричными литералами, поэтому 012345 - это 5349 в десятичной системе счисления. Вам не разрешено использовать восьмеричные литералы в строгом режиме.

VisioN 12.05.2020 16:35

Мои 2 цента: для неимперских (истов) парней

Paulo Bueno 30.09.2020 17:56

Как это сделать с событием на входе при наборе текста?

guilieen 30.11.2020 19:14

Эти встроенные функции форматирования несовместимы (требуются данные локали ...), поэтому это регулярное выражение - спаситель.

wilmol 20.01.2021 02:38

Вот реализация mootools 1.2 из кода, предоставленного XMLilley ...

Number.implement('format', function(decPlaces, thouSeparator, decSeparator){
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
decSeparator = decSeparator === undefined ? '.' : decSeparator;
thouSeparator = thouSeparator === undefined ? ',' : thouSeparator;

var num = this,
    sign = num < 0 ? '-' : '',
    i = parseInt(num = Math.abs(+num || 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, '' + thouSeparator) + (decPlaces ? decSeparator + Math.abs(num - i).toFixed(decPlaces).slice(2) : '');
});

Это может быть немного поздно, но вот метод, который я только что разработал для коллеги, чтобы добавить функцию .toCurrencyString() с учетом локали ко всем числам. Интернализация предназначена только для группировки номеров, а НЕ для знака валюты - если вы выводите доллары, используйте "$" в том виде, в котором он поставляется, потому что 3 4567 в Японии или Китае - это то же количество долларов США, что и ,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 "3,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"

Потому что почему бы не добавить еще один ответ. Я во многом основывал это на ответе VisioN.

function format (val) {
  val = (+val).toLocaleString();
  val = (+val).toFixed(2);
  val += "";
  return val.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "" + format.thousands);
}
(function (isUS) {
  format.decimal =   isUS ? "." : ",";
  format.thousands = isUS ? "," : ".";
}(("" + (+(0.00).toLocaleString()).toFixed(2)).indexOf(".") > 0));

Я тестировал входы:

[   ""
  , "1"
  , "12"
  , "123"
  , "1234"
  , "12345"
  , "123456"
  , "1234567"
  , "12345678"
  , "123456789"
  , "1234567890"
  , ".12"
  , "1.12"
  , "12.12"
  , "123.12"
  , "1234.12"
  , "12345.12"
  , "123456.12"
  , "1234567.12"
  , "12345678.12"
  , "123456789.12"
  , "1234567890.12"
  , "1234567890.123"
  , "1234567890.125"
].forEach(function (item) {
  console.info(format(item));
});

И получили такие результаты:

0.00
1.00
12.00
123.00
1,234.00
12,345.00
123,456.00
1,234,567.00
12,345,678.00
123,456,789.00
1,234,567,890.00
0.12
1.12
12.12
123.12
1,234.12
12,345.12
123,456.12
1,234,567.12
12,345,678.12
123,456,789.12
1,234,567,890.12
1,234,567,890.12
1,234,567,890.13

Просто для развлечения.

Intl.NumberFormat

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

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

  // These options are needed to round to whole numbers if that's what you want.
  //minimumFractionDigits: 0, // (this suffices for whole numbers, but will print 2500.10 as ,500.1)
  //maximumFractionDigits: 0, // (causes 2500.99 to be printed as ,501)
});

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

Скрипка JS

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

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

Intl.NumberFormat против Number.prototype.toLocaleString

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

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

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

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

  • Поддержка браузера больше не является проблемой в настоящее время: 98% поддержки во всем мире, 99% в США и более 99% в ЕС.
  • Существует прокладка для поддержки его в ископаемых браузерах (например, IE8), если вам действительно нужно
  • Если вы используете Node, вам мощь необходимо установить полный icu, см. здесь для получения дополнительной информации
  • Взгляните на Могу ли я использовать для получения дополнительной информации

Голосую за это, потому что это глупо простой ответ, который работает изначально.

Trasiva 31.08.2016 00:56

Совершенно уверен, что довольно большое количество браузеров теперь поддерживают это. За это следует проголосовать гораздо больше.

flq 24.12.2016 00:34

Это отличный ответ, и у меня он работает с динамической стоимостью валюты, поэтому, если используется в Европе, она меняется на евро и показывает знак евро. Работает удовольствие!

Sprose 14.09.2017 12:32

Отлично работает и в React Native!

flyandi 14.06.2018 01:48

Сейчас 2018 год, и это в основном поддерживается повсюду. Это должен быть правильный ответ.

sarink 27.09.2018 09:38

Поддерживается еще в Internet Explorer 11 (IE 11), а также поддерживаются все основные браузеры.

Matt Jensen 07.02.2020 18:04

есть ли способ отменить это, вернув 2500,00 долларов в строку, например 2500,00

RkuangDev 26.08.2020 04:57

@RkuangDev Конечно, но вам нужно знать используемый десятичный разделитель. Если это точка (самый простой сценарий), это будет работать: parseFloat(',345.67'.replace(/[^0-9.]/g, '')). Разумеется, остерегайтесь плавающих валютных курсов.

aross 26.08.2020 12:42

Почему это не принятый ответ? Красиво работает!

Olawale Oladiran 13.11.2020 18:46

Этот ответ соответствует следующим критериям:

  • Не зависит от внешней зависимости.
  • Поддерживает локализацию.
  • Есть тесты / доказательства.
  • Используются простые и передовые методы кодирования (без сложных регулярных выражений, используются стандартные шаблоны кодирования).

Этот код основан на концепциях из других ответов. Его скорость выполнения должна быть среди лучших, если это вызывает беспокойство.

var decimalCharacter = Number("1.1").toLocaleString().substr(1,1);
var defaultCurrencyMarker = "$";
function formatCurrency(number, currencyMarker) {
    if (typeof number != "number")
        number = parseFloat(number, 10);

    // if NaN is passed in or comes from the parseFloat, set it to 0.
    if (isNaN(number))
        number = 0;

    var sign = number < 0 ? "-" : "";
    number = Math.abs(number);  // so our signage goes before the $ symbol.

    var integral = Math.floor(number);
    var formattedIntegral = integral.toLocaleString();

    // IE returns "##.00" while others return "##"
    formattedIntegral = formattedIntegral.split(decimalCharacter)[0];

    var decimal = Math.round((number - integral) * 100);
    return sign + (currencyMarker || defaultCurrencyMarker) +
        formattedIntegral  +
        decimalCharacter +
        decimal.toString() + (decimal < 10 ? "0" : "");
}

Эти тесты работают только на компьютере с локализацией в США. Это решение было принято для простоты и потому, что это могло вызвать плохой ввод (плохая автоматическая локализация) и проблемы с выводом.

var tests = [
    // [ input, expected result ]
    [123123, "3,123.00"],    // no decimal
    [123123.123, "3,123.12"],    // decimal rounded down
    [123123.126, "3,123.13"],    // decimal rounded up
    [123123.4, "3,123.40"],  // single decimal
    ["123123", "3,123.00"],  // repeat subset of the above using string input.
    ["123123.123", "3,123.12"],
    ["123123.126", "3,123.13"],
    [-123, "-3.00"]  // negatives
];

for (var testIndex=0; testIndex < tests.length; testIndex++) {
    var test = tests[testIndex];
    var formatted = formatCurrency(test[0]);
    if (formatted == test[1]) {
        console.info("Test passed, \"" + test[0] + "\" resulted in \"" + formatted + "\"");
    } else {
        console.error("Test failed. Expected \"" + test[1] + "\", got \"" + formatted + "\"");
    }
}

Работает со всеми текущими браузерами

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

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

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

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

Поскольку аргументы «locales» и «options» поддерживаются очень небольшим количеством браузеров, например Chrome 24, IE11 и Opera 15. Firefox, Safari и другие более старые версии по-прежнему не поддерживают его.

VisioN 25.09.2013 10:50

Согласен, он не полностью поддерживается во всех браузерах (пока), но все же является решением. (И, возможно, наиболее верное решение, поскольку оно полностью совместимо с неподдерживаемыми браузерами, и это задокументированная функция Javascript api.)

Nick Grealy 26.09.2013 02:59

В MDN есть пример проверка поддержки локалей и аргументов опций

Jared Beck 26.09.2014 20:43

Мне это нравится, и я рад, что он работает с индийской группировкой цифр.

MSC 03.07.2016 09:35

Это полностью поддерживается по состоянию на 2017 год и должно быть единственно правильным ответом.

Evgeny 14.04.2017 18:33

Это не дает правильного общепринятого формата для en-ZA / ZAR (Южная Африка), поэтому, если вы находитесь в отдаленном регионе, вы можете зависеть от того, каким, по мнению постороннего, должен быть ваш формат.

avenmore 19.08.2019 20:50

@avenmore работает с последними версиями Chrome / Firefox / Safari. Ненавижу спрашивать ... но в каком браузере и какой версии вы тестируете?

Nick Grealy 20.08.2019 03:56

Последний и самый лучший :) FF69, Chrome76 и т. д. «2 500,00 рэнд» - это не то, что мы здесь используем, оно должно быть «2 500,00 рэндов», то же самое, что и en-GB.

avenmore 20.08.2019 10:59

@avenmore ... интересно ... Я провел небольшое расследование и TL; DR; запятая - официальный десятичный разделитель для Южной Африки. «Когда Южная Африка приняла метрическую систему, она приняла запятую в качестве десятичного разделителя, хотя в ряде домашних стилей, включая некоторые англоязычные газеты, такие как The Sunday Times, по-прежнему используется точка» - en.wikipedia.org/wiki/Decimal_separator. Однако вы можете переключать форматы с помощью (2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}).

Nick Grealy 20.08.2019 14:13

@Nick Grealy Спасибо за расследование, это проклятие южноафриканских программистов - разрывать вещи после неожиданной запятой. Я попробовал параметры, которые вы предлагаете, но в результате получилось «2500 рэндов», что тоже неприемлемо.

avenmore 20.08.2019 14:56

minimumFractionDigits: 2 именно то, что я искал!

Tim 24.10.2019 18:13

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

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

// usage: toCurrency(3939920.3030);

Ваше здоровье! Анунай

toCurrency('123456.7890') возвращает 123,456.7,890. ИМХО, в десятичных разрядах не должно быть запятых. В остальном выглядит хорошо!

Mike Causer 24.04.2014 12:44

Вот несколько решений, все проходят тестовый набор, тестовый набор и тестовый тест включены. Если вы хотите скопировать и вставить для тестирования, попробуйте Этот 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.info('======== Demo ========')
console.info(
    (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.info(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.info(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.info('======== 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.info(f);
    time = benchmark(function () {
        for (var i = 0; i < 100000; i++) {
            f.call(123456789, 0);
            f.call(123456789, 2);
        }
    });
    console.info(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.info('======== Benchmark ========');
async.push(function () { benchmark_format(Number.prototype.format); });
next();

Улучшено по сравнению с вашим методом 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 / множитель; если (String (a) .indexOf ('.') <1) {a + = '.00'; } a = String (a) .split ('.'), не используйте toFixed, потому что он содержит ошибки.

vee 18.10.2014 16:41

console.info (parseFloat ('4.835'). toFixed (2)); > 4.83 console.info (parseFloat ('54 .835 '). ToFixed (2)); > 54,84 console.info (parseFloat ('454.835'). ToFixed (2)); > 454,83 console.info (parseFloat ('8454.835'). ToFixed (2)); > 8454,83 десятичная дробь всех этих значений должна быть 0,84, а не 0,83

vee 18.10.2014 16:42

Функция для обработки вывода валюты, включая негативы. Выходной образец:
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, ",").toString();
}

Код от Jonathan M кажется мне сложным, поэтому я переписал его и получил около 30% на FF v30 и 60% на повышении скорости Chrome v35 (http://jsperf.com/number-formating2):

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, "" + thouSeparator));
    }
    return i+j;
};

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

var sum = 123456789.5698;
var formatted = '$' + sum.formatNumber(2,',','.'); // "3,456,789.57"

Мне нравится просто:

function formatPriceUSD(price) {
    var strPrice = price.toFixed(2).toString();
    var a = strPrice.split('');

    if (price > 1000000000)
        a.splice(a.length - 12, 0, ',');

    if (price > 1000000)
        a.splice(a.length - 9, 0, ',');

    if (price > 1000)
        a.splice(a.length - 6, 0, ',');

    return '$' + a.join("");
}

Intl.NumberFormat

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

или phpjs.com/functions/number_format

Просил решение JS!

Bhargav Nanekalva 26.06.2015 22:16

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

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

var number = 123456.789;

// German uses comma as decimal separator and period for thousands console.info(new Intl.NumberFormat('de-DE').format(number)); // → 123.456,789

// Arabic in most Arabic speaking countries uses real Arabic digits console.info(new Intl.NumberFormat('ar-EG').format(number)); // → ١٢٣٤٥٦٫٧٨٩

// India uses thousands/lakh/crore separators console.info(new Intl.NumberFormat('en-IN').format(number));

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

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

создаст строку "-3.00".

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

Этот ответ был почти у меня, но мне нужно было округлить его до ближайшей копейки. Это то, что я использовал amount.toLocaleString ('en-GB', {style: 'currency', currency: 'GBP', maximumFractionDigits: 2});

Nico 18.11.2014 14:47

Приведенный выше код округляет до желаемого количества цифр. См. Пример и введите 1,237 в поле ввода.

Daniel Barbalace 26.03.2015 20:36

Кажется, не работает в Safari. Он просто возвращает число в виде строки без какого-либо форматирования.

Lance Anderson 08.05.2015 06:22

Документация MDN для всех, кто хотел бы увидеть полный набор опций.

Mark Carpenter Jr 27.06.2017 17:20

Вау, это действительно отличный ответ. Должно быть наверху.

Ethan 15.07.2017 02:56

Если по какой-то причине вам не нужны центы, вы можете изменить десятичную точность с помощью: minimumFractionDigits: 0

Horacio 29.05.2018 19:50

@Horacio / Nico - см. Предыдущий ответ: stackoverflow.com/a/18994850/782034

Nick Grealy 18.05.2019 17:39

Мне нравится самый короткий ответ VisionN, за исключением случаев, когда мне нужно изменить его для числа без десятичной точки (123 доллара вместо 123 долларов США), он не работает, поэтому вместо быстрого копирования / вставки мне нужно расшифровать загадочный синтаксис регулярного выражения JavaScript.

Вот оригинальное решение

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

Сделаю немного длиннее:

var re = /\d(?=(\d{3})+\.)/g;
var subst = '$&,';
n.toFixed(2).replace(re, subst);

Часть Re здесь (часть поиска в строке заменить) означает

  1. Найти все цифры (\d)
  2. Далее следует (?= ...) (взгляд вперед)
  3. Одна или несколько групп ( ... )+
  4. Ровно 3 цифры (\d{3})
  5. Окончание с точкой (\.)
  6. Сделайте это для всех случаев (g)

Subst здесь означает

  1. Каждый раз, когда есть совпадение, замените его самим собой ($&), за которым следует запятая.

Поскольку мы используем string.replace, весь остальной текст в строке остается прежним, и только найденные цифры (те, за которыми следуют 3,6,9 и т. д. Другие цифры) получают дополнительную запятую.

Таким образом, в числе 1234567,89 цифры 1 и 4 удовлетворяют условию (1234567.89) и заменяются на «1,» и «4,», в результате чего получается 1 234 567,89.

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

var re2 = /\d(?=(\d{3})+$)/g;

Он полагается на конец строки ($) вместо точки (\.), и окончательное выражение будет (обратите внимание также на toFixed(0)):

n.toFixed(0).replace(/\d(?=(\d{3})+$)/g, '$&,');

Это выражение даст

1234567.89 -> 1,234,567

Кроме того, вместо конца строки ($) в регулярном выражении выше вы также можете выбрать границу слова (\b).

Приношу свои извинения заранее, если я неправильно истолковал какую-либо часть обработки регулярных выражений.

После десятичной дроби вам нужны только две (2) цифры, например, предположим, что ваш формат валюты - это 22.2737, в это время вы можете использовать следующее решение для получения результата в этом формате 22.27, функция currencyFormat (num) {return parseFloat (num) .toFixed (2); } var moneyWithDecimal = currencyFormat (22.2737); alert (moneyWithDecimal);

Amzad Khan 03.05.2020 15:44

многие ответы содержали полезные идеи, но ни один из них не соответствовал моим потребностям. Итак, я использовал все идеи и построил этот пример:

function Format_Numb( fmt){
    var decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
    if (typeof decSgn== = "undefined") decSgn = ".";
    if (typeof kommaSgn== = "undefined") kommaSgn= ",";

    var s3digits=/(\d{1,3}(?=(\d{3})+(?=[.]|$))|(?:[.]\d*))/g;
    var dflt_nk = "00000000".substring(0,decimals);

    //--------------------------------
    // handler for pattern: "%m"
    var _f_money= function( v_in){
                var v=v_in.toFixed(decimals);
                var add_nk = ",00";
                var arr=    v.split(".");
                return     arr[0].toString().replace(s3digits, function ($0) {
                                    return ($0.charAt(0)= = ".")
                                        ? ((add_nk = ""),(kommaSgn + $0.substring(1)))
                                        : ($0 + decSgn);
                        })
                        + (    (decimals > 0)
                                ?    (    kommaSgn
                                        + (
                                            (arr.length > 1)
                                            ? arr[1]
                                            : dflt_nk
                                        )
                                    )
                                :    ""                    
                        );
    }

    // handler for pattern: "%<len>[.<prec>]f"
    var _f_flt= function( v_in,l,prec){
        var v=(typeof prec !== "undefined") ? v_in.toFixed(prec):v_in;
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l+1).join(" ") + v)
                :v;
    }

    // handler for pattern: "%<len>x"
    var _f_hex= function( v_in,l,flUpper){
        var v=    Math.round(v_in).toString(16);
        if (flUpper)    v=v.toUpperCase();
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l+1).join("0") + v)
                :v;        
    }

    //...can be extended..., just add the function, f.e.:    var _f_octal= function( v_in,...){
    //--------------------------------

    if ( typeof(fmt)!= = "undefined"){
        //...can be extended..., just add the char,f.e."O":    MFX -> MFXO
        var rpatt=/(?:%([^%"MFX]*)([MFX]))|(?:"([^"]*)")|("|%%)/gi;
        var _qu=    "\"";
        var _mask_qu=    "\\\"";
        var str=    fmt.toString().replace( rpatt,function($0,$1,$2,$3,$4){
                                var f;
                                if (typeof $1 !== "undefined"){
                                    switch($2.toUpperCase()){
                                        case "M":    f= "_f_money(v)";    break;
                                        case "F":    var    n_dig0,n_dig1;
                                                var    re_flt=/^(?:(\d))*(?:[.](\d))*$/;
                                                $1.replace(re_flt,function($0,$1,$2){
                                                    n_dig0=$1;
                                                    n_dig1=$2;
                                                });
                                                f= "_f_flt(v," + n_dig0 + "," + n_dig1 + ")";    break;
                                        case "X":    var    n_dig = "undefined";
                                                var    re_flt=/^(\d*)$/;
                                                $1.replace(re_flt,function($0){
                                                    if ($0! = "")n_dig=$0;
                                                });
                                                f= "_f_hex(v," + n_dig + "," + ($2= = "X") + ")";    break;
                                        //...can be extended..., f.e.:    case "O":
                                    }
                                    return "\"+"+f+"+\"";
                                } else if (typeof $3 !== "undefined"){
                                    return _mask_qu + $3 + _mask_qu;
                                } else {
                                    return ($4==_qu)?_mask_qu:$4.charAt(0);
                                }
                            });
        var cmd=        "return function(v){"
                +        "if (typeof v === \"undefined\")return \"\";"    //null returned as empty string
                +        "if (!v.toFixed)return v.toString();"        //not numb returned as string
                +        "return \"" + str + "\";"
                +    "}";

        //...can be extended..., just add the function name in the 2 places:
        return new Function( "_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
    }
}

Во-первых, мне нужно было определение строки формата C-стиль, которое должно быть гибкий, но очень простой в использовании, и я определил его следующим образом; шаблоны:

%[<len>][.<prec>]f        float, example "%f", "%8.2d", "%.3f"
%m                        money
%[<len>]x                 hexadecimal lower case, example "%x", "%8x"
%[<len>]X                 hexadecimal upper case, example "%X", "%8X"

поскольку для меня нет необходимости форматировать другие файлы в евро, я реализовал только "% m". Но это легко продлить ... Как и в C, строка формата - это строка, содержащая шаблоны, например за евро: "% m €" (возвращает такие строки, как «8,129,33 €»)

Помимо гибкости, мне нужен был очень быстрое решение для обработки таблиц. Это означает, что при обработке тысяч ячеек выполняется обработка строки формата нельзя делать более одного раза. Вызов типа "format (value, fmt)" для меня неприемлем, но его нужно разбить на два этапа:

// var formatter = Format_Numb( "%m €");  
//simple example for Euro...

//   but we use a complex example: 

var formatter = Format_Numb("a%%%3mxx \"zz\"%8.2f°\"  >0x%8X<");

// formatter is now a function, which can be used more than once (this is an example, that can be tested:) 

var v1= formatter( 1897654.8198344); 

var v2= formatter( 4.2); 

... (and thousands of rows)

Также для повышения производительности _f_money включает регулярное выражение;

В-третьих, такой вызов, как «формат (значение, fmt)», неприемлем, потому что: Хотя должна быть возможность форматировать разные коллекции объектов (например, ячейки столбца) с разными масками, я не хочу иметь что-то для обработки строк форматирования в точке обработки. На данный момент я хочу только ИСПОЛЬЗОВАТЬ форматирование, как в

for( var cell in cells){ do_something( cell.col.formatter( cell.value)); }

Какой формат - может быть, он определен в ini, в xml для каждого столбца или где-то еще ..., но анализ и установка форматов или имеет дело с интернационализацией обрабатывается совершенно в другом месте, и там я хочу назначить средство форматирования для коллекции, не думая о проблемах с производительностью:

col.formatter = Format_Numb( _getFormatForColumn(...) );

В-четвертых, я хотел «терпимое» решение, поэтому проходя мимо, например, строка вместо числа должна возвращать просто строку, а "null" должна возвращать пустую строку.

(Также форматирование "% 4.2f" не должно сокращать что-либо, если значение слишком велико.)

И последнее, но не менее важное - это должно быть читаемый и легко расширяемый, БЕЗ влияния на производительность ... Например, если кому-то нужны «восьмеричные значения», обратитесь к строкам с «... может быть расширено ...» - я думаю, это должно быть очень простой задачей.

В целом я сосредоточился на производительности. Каждую «процедуру обработки» (например, _f_money) можно инкапсулировать, оптимизировать или обменять с другими идеями в том или другом потоке без изменения «процедур подготовки» (анализ строк формата и создание функций), которые должны обрабатываться только один раз и в этом Смысл не так критичен к производительности, как вызовы преобразования тысяч номеров.

Для всех, кто предпочитает числовые методы:

Number.prototype.format_euro=( function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%m €"));

var v_euro= (8192.3282).format_euro(); //results: 8.192,33 €

Number.prototype.format_hex= (function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%4x"));

var v_hex= (4.3282).format_hex();

Хотя я что-то тестировал, в коде может быть много ошибок. Так что это не готовый модуль, а просто идея и отправная точка для таких не-js-экспертов, как я. Код содержит множество и мало измененных идей из множества сообщений stackoverflow; извините, я не могу сослаться на все из них, но спасибо всем экспертам.

Уже есть хорошие ответы. Вот простая попытка развлечься:

function currencyFormat(no) {
  var ar = (+no).toFixed(2).split('.');
  return [
      numberFormat(ar[0]|0),
      '.', 
      ar[1]
  ].join('');
}


function numberFormat(no) {
  var str = no + '';
  var ar = [];
  var i  = str.length -1;

  while( i >= 0 ) {
    ar.push( (str[i-2]||'') + (str[i-1]|| '')+ (str[i]|| ''));
    i= i-3;
  }
  return ar.reverse().join(',');  
}

Выполните несколько примеров

console.info(
  currencyFormat(1),
  currencyFormat(1200),
  currencyFormat(123),
  currencyFormat(9870000),
  currencyFormat(12345),
  currencyFormat(123456.232)
)

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

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

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

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

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.

Не согласовано во всех браузерах: /

stackoverfloweth 09.06.2015 05:33

Спасибо за предупреждение @godmode. С какими браузерами вы столкнулись с проблемами?

Ken Palmer 09.06.2015 16:25

В Safari 8.0.6 не было обрезки десятичных знаков, вставки символа «$» или добавления запятых.

stackoverfloweth 09.06.2015 16:53

Возникла идея использовать toLocaleString (), но упала на поплавок. Как отмечалось ранее, валюта никогда не должна храниться в плавающем состоянии.

tggagne 19.08.2015 16:32

Спасибо @tggagne, вы правы. Плохой контроль с моей стороны.

Ken Palmer 19.08.2015 18:43

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, "" + ",").replace(/^0*(?=.)/,"");
          return "$" + str + "." + decimal;
        }

Я хочу внести свой вклад в это:

function toMoney(amount) {
    neg = amount.charAt(0);
    amount= amount.replace(/\D/g, '');
    amount= amount.replace(/\./g  , '');
    amount= amount.replace(/\-/g, '');

    var numAmount = new Number(amount); 
    amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
        return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "." + c : c;
    });

    if (neg == '-')
        return neg+amount;
    else
        return amount;
}

Это позволяет вам преобразовывать числа в текстовое поле, в которое вы можете вводить только числа (рассмотрите этот сценарий).

Это очистит текстовое поле, в котором предполагается использовать только числа, даже если вы вставляете строку с цифрами и буквами или любым символом.

<html>
<head>
<script language= = "Javascript">
function isNumber(evt) {    
    var theEvent = evt || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode(key);
    if (key.length == 0) return;
    var regex = /^[0-9\-\b]+$/;
    if (!regex.test(key)) {
        theEvent.returnValue = false;
        if (theEvent.preventDefault) theEvent.preventDefault();
    }
}
function toMoney(amount) {
    neg = amount.charAt(0);
    amount= amount.replace(/\D/g, '');
    amount= amount.replace(/\./g  , '');
    amount= amount.replace(/\-/g, '');

    var numAmount = new Number(amount); 
    amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
        return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "." + c : c;
    });

    if (neg == '-')
        return neg+amount;
    else
        return amount;
}
function clearText(inTxt, newTxt, outTxt) {
    inTxt = inTxt.trim();
    newTxt = newTxt.trim();
    if (inTxt == '' || inTxt == newTxt) 
        return outTxt;

    return inTxt;   
}

function fillText(inTxt, outTxt) {
    inTxt = inTxt.trim();
    if (inTxt != '') 
        outTxt = inTxt;

    return outTxt;
}
</script>
</head>
<body>
$ <input name=reca2 id=reca2 type=text value = "0" onFocus = "this.value = clearText(this.value, '0', '');" onblur = "this.value = fillText(this.value, '0'); this.value = toMoney(this.value);" onKeyPress = "isNumber(event);" style = "width:80px;" />
</body>
</html>

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

// Default usage:
accounting.formatMoney(12345678); // ,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€ 

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

user285594 07.06.2017 10:59

toLocaleString - это хорошо, но работает не во всех браузерах. Обычно я использую currencyFormatter.js (https://osrec.github.io/currencyFormatter.js/). Он довольно легкий и содержит все определения валюты и локали прямо из коробки. Он также хорош для форматирования необычно отформатированных валют, таких как INR (который группирует числа в лакхах и крорах и т. д.). Также никаких зависимостей!

OSREC.CurrencyFormatter.format(2534234, { currency: 'INR' }); // Returns ₹ 25,34,234.00

OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR' }); // Returns 2.534.234,00 €

OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR', locale: 'fr' }); // Returns 2 534 234,00 €

Ничего подобного не видел. Он краток, прост для понимания и не полагается на какие-либо излишне сложные регулярные выражения.

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.info(
  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.info(
  formatPound(1000),
  formatDollar(10000.0066),
  formatEuro(100000.001),
  customFormat(999999.555)
)

Отличный фрагмент кода, спасибо. Однако будьте осторожны, так как это не будет работать в IE, потому что параметры по умолчанию не поддерживаются, а «const» и «let» не поддерживаются в <IE11. Используйте это, чтобы исправить: + moneyFormat: function (price, sign) {+ if (! Sign) sign = '$'; + piece = parseFloat (цена) .toFixed (2) .split ('') + var ii = piece.length - 3

Charlie Dalsass 21.11.2016 20:52

Не беспокойся @CharlieDalsass. Я бы рекомендовал использовать babel, чтобы скомпилировать его до ES5 для производственного кода.

synthet1c 23.11.2016 12:35

Но как сделать евро валютой? 1.000,00 евро?

user285594 06.06.2017 18:41

@YumYumYum Я добавил полный пример с большим количеством параметров форматирования, чтобы обеспечить большую гибкость.

synthet1c 07.06.2017 07:53

Мне было сложно найти простую библиотеку для работы с датой и валютой, поэтому я создал свою: https://github.com/dericeira/slimFormatter.js

Просто как тот:

var number = slimFormatter.currency(2000.54);

Вот простой форматтер в vanilla JS:

function numberFormatter (num) {
        console.info(num)
    var wholeAndDecimal = String(num.toFixed(2)).split(".");
    console.info(wholeAndDecimal)
    var reversedWholeNumber = Array.from(wholeAndDecimal[0]).reverse();
    var formattedOutput = [];

    reversedWholeNumber.forEach( (digit, index) => {
        formattedOutput.push(digit);
        if ((index + 1) % 3 === 0 && index < reversedWholeNumber.length - 1) {
            formattedOutput.push(",");
        }
    })

    formattedOutput = formattedOutput.reverse().join('') + "." + wholeAndDecimal[1];

    return formattedOutput;

}

Потому что каждая проблема заслуживает решения в одну строку:

Number.prototype.formatCurrency = function() { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, ',') : t + '.' + c; }, '$'); }

Это достаточно легко изменить для разных языков, просто замените «$ 1» на «$ 1». и '.' в ',' поменять местами и. в числах, а символ валюты можно изменить, изменив знак «$» в конце.

Или, если у вас есть ES6, вы можете просто объявить функцию со значениями по умолчанию:

Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = '$') { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '' + thou) : t + dec + c; }, sym); }

console.info((4215.57).formatCurrency())
,215.57
console.info((4216635.57).formatCurrency('.', ','))
.216.635,57
console.info((4216635.57).formatCurrency('.', ',', "\u20AC"))
€4.216.635,57

Да, и это работает и для отрицательных чисел:

console.info((-6635.574).formatCurrency('.', ',', "\u20AC"))
-€6.635,57
console.info((-1066.507).formatCurrency())
-,066.51

И, конечно, вам не обязательно иметь символ валюты.

console.info((1234.586).formatCurrency(',','.',''))
1,234.59
console.info((-7890123.456).formatCurrency(',','.',''))
-7,890,123.46
console.info((1237890.456).formatCurrency('.',',',''))
1.237.890,46

Я хотел ванильное решение javascript, которое автоматически возвращало десятичную часть.

function formatDollar(amount) {
    var dollar = Number(amount).toLocaleString("us", "currency");
    //decimals
    var arrAmount = dollar.split(".");
    if (arrAmount.length==2) {
        var decimal = arrAmount[1];
        if (decimal.length==1) {
            arrAmount[1] += "0";
        }
    }
    if (arrAmount.length==1) {
        arrAmount.push("00");
    }

    return "$" + arrAmount.join(".");
}


console.info(formatDollar("1812.2");

Number(value)
        .toFixed(2)
        .replace(/(\d)(?=(\d{3})+(?!\d))/g, ",")

Пожалуйста, найдите в приведенном ниже коде то, что я разработал для поддержки интернационализации. Может кому-нибудь помочь. Он форматирует данное числовое значение в формат, специфичный для языка. В данном примере я использовал ‘En’, пока тестировал ‘Es’, ‘Fr’ и другие страны, где формат меняется. Он не только не позволяет пользователю вводить символы, но и форматирует значение при выводе табуляции. Созданы компоненты для формата Число, а также для формата Десятичная дробь. Помимо этого были созданы функции parseNumber (значение, языковой стандарт) и parseDecimal (значение, языковой стандарт), которые будут анализировать отформатированные данные для любых других бизнес-целей. Указанная функция примет форматированные данные и вернет неформатированное значение. Я использовал плагин валидатора JQuery в приведенном ниже общем коде.

HTML:

<tr>
                        <td>
                            <label class = "control-label">
                                Number Field:
                            </label>
                            <div class = "inner-addon right-addon">                                        
                                <input type = "text" id = "numberField" 
                                       name = "numberField"
                                       class = "form-control"
                                       autocomplete = "off"
                                       maxlength = "17"
                                       data-rule-required = "true"
                                       data-msg-required = "Cannot be blank."
                                       data-msg-maxlength = "Exceeding the maximum limit of 13 digits. Example: 1234567890123"
                                       data-rule-numberExceedsMaxLimit = "en"
                                       data-msg-numberExceedsMaxLimit = "Exceeding the maximum limit of 13 digits. Example: 1234567890123"
                                       onkeydown = "return isNumber(event, 'en')"
                                       onkeyup = "return updateField(this)"
                                       onblur = "numberFormatter(this,                                                           
                                                   'en', 
                                                   'Invalid character(s) found. Please enter valid characters.')">
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <label class = "control-label">
                                Decimal Field:
                            </label>
                            <div class = "inner-addon right-addon">                                        
                                <input type = "text" id = "decimalField" 
                                       name = "decimalField"
                                       class = "form-control"
                                       autocomplete = "off"
                                       maxlength = "20"
                                       data-rule-required = "true"
                                       data-msg-required = "Cannot be blank."
                                       data-msg-maxlength = "Exceeding the maximum limit of 16 digits. Example: 1234567890123.00"
                                       data-rule-decimalExceedsMaxLimit = "en"
                                       data-msg-decimalExceedsMaxLimit = "Exceeding the maximum limit of 16 digits. Example: 1234567890123.00"
                                       onkeydown = "return isDecimal(event, 'en')"
                                       onkeyup = "return updateField(this)"
                                       onblur = "decimalFormatter(this,
                                           'en', 
                                           'Invalid character(s) found. Please enter valid characters.')">
                            </div>
                        </td>
                    </tr>

JavaScript:

/* 
 * @author: dinesh.lomte
 */
/* Holds the maximum limit of digits to be entered in number field. */
var numericMaxLimit = 13;
/* Holds the maximum limit of digits to be entered in decimal field. */
var decimalMaxLimit = 16;

/**
 * 
 * @param {type} value
 * @param {type} locale
 * @returns {Boolean}
 */
parseDecimal = function(value, locale) {

    value = value.trim();
    if (isNull(value)) {
        return 0.00;
    }
    if (isNull(locale)) {
        return value;
    }
    if (getNumberFormat(locale)[0] === '.') {
        value = value.replace(/\./g, '');
    } else {
        value = value.replace(
                new RegExp(getNumberFormat(locale)[0], 'g'), '');
    }
    if (getNumberFormat(locale)[1] === ',') {
        value = value.replace(
                new RegExp(getNumberFormat(locale)[1], 'g'), '.');
    }
    return value;
};

/**
 * 
 * @param {type} element
 * @param {type} locale
 * @param {type} nanMessage
 * @returns {Boolean}
 */
decimalFormatter = function (element, locale, nanMessage) {

    showErrorMessage(element.id, false, null);
    if (isNull(element.id) || isNull(element.value) || isNull(locale)) {
        return true;
    }
    var value = element.value.trim();
    value = value.replace(/\s/g, '');
    value = parseDecimal(value, locale);
    var numberFormatObj = new Intl.NumberFormat(locale,
            {   minimumFractionDigits: 2,
                maximumFractionDigits: 2
            }
    );
    if (numberFormatObj.format(value) === 'NaN') {
        showErrorMessage(element.id, true, nanMessage);
        setFocus(element.id);
        return false;
    }
    element.value =
            numberFormatObj.format(value);
    return true;
};

/**
 * 
 * @param {type} element
 * @param {type} locale
 * @param {type} nanMessage
 * @returns {Boolean}
 */
numberFormatter = function (element, locale, nanMessage) {

    showErrorMessage(element.id, false, null);
    if (isNull(element.id) || isNull(element.value) || isNull(locale)) {
        return true;
    }
    var value = element.value.trim();    
    var format = getNumberFormat(locale);
    if (hasDecimal(value, format[1])) {
        showErrorMessage(element.id, true, nanMessage);
        setFocus(element.id);
        return false;
    }
    value = value.replace(/\s/g, '');
    value = parseNumber(value, locale);
    var numberFormatObj = new Intl.NumberFormat(locale,
            {   minimumFractionDigits: 0,
                maximumFractionDigits: 0
            }
    );
    if (numberFormatObj.format(value) === 'NaN') {
        showErrorMessage(element.id, true, nanMessage);
        setFocus(element.id);
        return false;
    }
    element.value =
            numberFormatObj.format(value);
    return true;
};

/**
 * 
 * @param {type} id
 * @param {type} flag
 * @param {type} message
 * @returns {undefined}
 */
showErrorMessage = function(id, flag, message) {

    if (flag) {
        // only add if not added
        if ($('#'+id).parent().next('.app-error-message').length === 0) {
            var errorTag = '<div class=\'app-error-message\'>' + message + '</div>';
            $('#'+id).parent().after(errorTag);
        }
    } else {
        // remove it
        $('#'+id).parent().next(".app-error-message").remove(); 
    }
};

/**
 * 
 * @param {type} id             
 * @returns
 */
setFocus = function(id) {

    id = id.trim();
    if (isNull(id)) {
        return;
    }
    setTimeout(function() {
        document.getElementById(id).focus();
    }, 10);
};

/**
 * 
 * @param {type} value
 * @param {type} locale
 * @returns {Array}
 */
parseNumber = function(value, locale) {

    value = value.trim();
    if (isNull(value)) {
        return 0;
    }    
    if (isNull(locale)) {
        return value;
    }
    if (getNumberFormat(locale)[0] === '.') {
        return value.replace(/\./g, '');
    }
    return value.replace(
            new RegExp(getNumberFormat(locale)[0], 'g'), '');
};

/**
 * 
 * @param {type} locale
 * @returns {Array}
 */
getNumberFormat = function(locale) {

    var format = [];
    var numberFormatObj = new Intl.NumberFormat(locale,
            {   minimumFractionDigits: 2,
                maximumFractionDigits: 2
            }
    );
    var value = numberFormatObj.format('132617.07');
    format[0] = value.charAt(3);
    format[1] = value.charAt(7);
    return format;
};

/**
 * 
 * @param {type} value
 * @param {type} fractionFormat
 * @returns {Boolean}
 */
hasDecimal = function(value, fractionFormat) {

    value = value.trim();
    if (isNull(value) || isNull(fractionFormat)) {
        return false;
    }
    if (value.indexOf(fractionFormat) >= 1) {
        return true;
    }
};

/**
 * 
 * @param {type} event
 * @param {type} locale
 * @returns {Boolean}
 */
isNumber = function(event, locale) {

    var keyCode = event.which ? event.which : event.keyCode;
    // Validating if user has pressed shift character
    if (keyCode === 16) {
        return false;
    }
    if (isNumberKey(keyCode)) {        
        return true;
    }
    var numberFormatter = [32, 110, 188, 190];
    if (keyCode === 32
            && isNull(getNumberFormat(locale)[0]) === isNull(getFormat(keyCode))) {
        return true;
    }
    if (numberFormatter.indexOf(keyCode) >= 0
            && getNumberFormat(locale)[0] === getFormat(keyCode)) {        
        return true;
    }    
    return false;
};

/**
 * 
 * @param {type} event
 * @param {type} locale
 * @returns {Boolean}
 */
isDecimal = function(event, locale) {

    var keyCode = event.which ? event.which : event.keyCode;
    // Validating if user has pressed shift character
    if (keyCode === 16) {
        return false;
    }
    if (isNumberKey(keyCode)) {
        return true;
    }
    var numberFormatter = [32, 110, 188, 190];
    if (keyCode === 32
            && isNull(getNumberFormat(locale)[0]) === isNull(getFormat(keyCode))) {
        return true;
    }
    if (numberFormatter.indexOf(keyCode) >= 0
            && (getNumberFormat(locale)[0] === getFormat(keyCode)
                || getNumberFormat(locale)[1] === getFormat(keyCode))) {
        return true;
    }
    return false;
};

/**
 * 
 * @param {type} keyCode
 * @returns {Boolean}
 */
isNumberKey = function(keyCode) {

    if ((keyCode >= 48 && keyCode <= 57)
            || (keyCode >= 96 && keyCode <= 105)) {        
        return true;
    }
    var keys = [8, 9, 13, 35, 36, 37, 39, 45, 46, 109, 144, 173, 189];
    if (keys.indexOf(keyCode) !== -1) {        
        return true;
    }
    return false;
};

/**
 * 
 * @param {type} keyCode
 * @returns {JSON@call;parse.numberFormatter.value|String}
 */
getFormat = function(keyCode) {

    var jsonString = '{"numberFormatter" : [{"key":"32", "value":" ", "description":"space"}, {"key":"188", "value":",", "description":"comma"}, {"key":"190", "value":".", "description":"dot"}, {"key":"110", "value":".", "description":"dot"}]}';
    var jsonObject = JSON.parse(jsonString);
    for (var key in jsonObject.numberFormatter) {
        if (jsonObject.numberFormatter.hasOwnProperty(key)
                && keyCode === parseInt(jsonObject.numberFormatter[key].key)) {
            return jsonObject.numberFormatter[key].value;
        }
    }
    return '';
};

/**
 * 
 * @type String
 */
var jsonString = '{"shiftCharacterNumberMap" : [{"char":")", "number":"0"}, {"char":"!", "number":"1"}, {"char":"@", "number":"2"}, {"char":"#", "number":"3"}, {"char":"$", "number":"4"}, {"char":"%", "number":"5"}, {"char":"^", "number":"6"}, {"char":"&", "number":"7"}, {"char":"*", "number":"8"}, {"char":"(", "number":"9"}]}';

/**
 * 
 * @param {type} value
 * @returns {JSON@call;parse.shiftCharacterNumberMap.number|String}
 */
getShiftCharSpecificNumber = function(value) {

    var jsonObject = JSON.parse(jsonString);
    for (var key in jsonObject.shiftCharacterNumberMap) {
        if (jsonObject.shiftCharacterNumberMap.hasOwnProperty(key)
                && value === jsonObject.shiftCharacterNumberMap[key].char) {
            return jsonObject.shiftCharacterNumberMap[key].number;
        }
    }
    return '';
};

/**
 * 
 * @param {type} value
 * @returns {Boolean}
 */
isShiftSpecificChar = function(value) {

    var jsonObject = JSON.parse(jsonString);
    for (var key in jsonObject.shiftCharacterNumberMap) {
        if (jsonObject.shiftCharacterNumberMap.hasOwnProperty(key)
                && value === jsonObject.shiftCharacterNumberMap[key].char) {
            return true;
        }
    }
    return false;
};

/**
 * 
 * @param {type} element
 * @returns {undefined}
 */
updateField = function(element) {

    var value = element.value;

    for (var index = 0; index < value.length; index++) {
        if (!isShiftSpecificChar(value.charAt(index))) {
            continue;
        }
        element.value = value.replace(
                value.charAt(index),
                getShiftCharSpecificNumber(value.charAt(index)));
    }
};

/**
 * 
 * @param {type} value
 * @param {type} element
 * @param {type} params
 */
jQuery.validator.addMethod('numberExceedsMaxLimit', function(value, element, params) {

    value = parseInt(parseNumber(value, params));
    if (value.toString().length > numericMaxLimit) {
        showErrorMessage(element.id, false, null);
        setFocus(element.id);
        return false;
    }    
    return true;
}, 'Exceeding the maximum limit of 13 digits. Example: 1234567890123.');

/**
 * 
 * @param {type} value
 * @param {type} element
 * @param {type} params
 */
jQuery.validator.addMethod('decimalExceedsMaxLimit', function(value, element, params) {

    value = parseFloat(parseDecimal(value, params)).toFixed(2);    
    if (value.toString().substring(
            0, value.toString().lastIndexOf('.')).length > numericMaxLimit
            || value.toString().length > decimalMaxLimit) {
        showErrorMessage(element.id, false, null);
        setFocus(element.id);
        return false;
    }    
    return true;
}, 'Exceeding the maximum limit of 16 digits. Example: 1234567890123.00.');

/**
 * @param {type} id
 * @param {type} locale
 * @returns {boolean}
 */
isNumberExceedMaxLimit = function(id, locale) {

    var value = parseInt(parseNumber(
            document.getElementById(id).value, locale));
    if (value.toString().length > numericMaxLimit) {
        setFocus(id);
        return true;
    }    
    return false;
};

/**
 * @param {type} id
 * @param {type} locale
 * @returns {boolean}
 */
isDecimalExceedsMaxLimit = function(id, locale) {

    var value = parseFloat(parseDecimal(
            document.getElementById(id).value, locale)).toFixed(2);
    if (value.toString().substring(
            0, value.toString().lastIndexOf('.')).length > numericMaxLimit
            || value.toString().length > decimalMaxLimit) {
        setFocus(id);
        return true;
    }
    return false;
};

Мы также можем использовать numeraljs

Numbers can be formatted to look like currency, percentages, times, or even plain old numbers with decimal places, thousands, and abbreviations. And you can always create a custom format.

var string = numeral(1000).format('0,0');
// '1,000'

* Пожалуйста, попробуйте приведенные ниже коды

"250000".replace(/(\d)(?=(\d{3})+(?!\d))/g, ',');

Ans: 250,000

Вы можете использовать Intl изначально следующим образом:

// value: 11.07

Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value)

// result: R$ 11,07

документация: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl

надеюсь это поможет! ;)

Чем это отличается от моего ответа? stackoverflow.com/a/16233919/1000608

aross 06.07.2020 17:09

Взяв несколько из лучших ответов, я объединил и создал функцию ES6, которая передает eslinter.

export const formatMoney = (
  amount,
  decimalCount = 2,
  decimal = '.',
  thousands = ',',
  currencySymbol = '$',
) => {
  if (typeof Intl === 'object') {
    return new Intl.NumberFormat('en-AU', {
      style: 'currency',
      currency: 'AUD',
    }).format(amount);
  }
  // fallback if Intl is not present.
  try {
    const negativeSign = amount < 0 ? '-' : '';
    const amountNumber = Math.abs(Number(amount) || 0).toFixed(decimalCount);
    const i = parseInt(amountNumber, 10).toString();
    const j = i.length > 3 ? i.length % 3 : 0;
    return (
      currencySymbol +
      negativeSign +
      (j ? i.substr(0, j) + thousands : '') +
      i.substr(j).replace(/(\d{3})(?=\d)/g, `${thousands}`) +
      (decimalCount
        ? decimal +
          Math.abs(amountNumber - i)
            .toFixed(decimalCount)
            .slice(2)
        : '')
    );
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error(e);
  }
  return amount;
};

Другие вопросы по теме