Luke
Luke

Reputation: 19961

How to determine thousands separator in JavaScript

In order for toLocaleString to work, the browser/JavaScript must know the user's locale and whether or not the specific locale uses "," or "." for a thousands separator. Is it possible to access this data so that we can determine what the thousands separator is?

If not, we can use a function like this...

var thousandsSeparator = (function(){
    if (typeof Number.prototype.toLocaleString === 'function') {
        var num = 1000;
        var numStr = num.toLocaleString();
        if (numStr.length == 5) {
            return numStr.substr(1, 1);
        }
    }
    return ","; // fall-back
})();

...but it feels like an unnecessary hack.

Upvotes: 13

Views: 3501

Answers (3)

David Min
David Min

Reputation: 1414

You can use the formatToParts() function (MDN) on Intl.NumberFormat to try to get the separator:

const separator = new Intl.NumberFormat().formatToParts(1000)[1].value

Upvotes: 1

Pedro Mora
Pedro Mora

Reputation: 385

Easy, I guess. This should help you to start with this ES6 solution

function getThousandSeparator(locale){
  const mapperRE = /(.{1})\d{3}(\D)\d$/,
    digitRE = /\d/,
    formattedValue = (new Intl.NumberFormat(locale?? navigator.language)).format(1000.1);
  let [_,thousand, decimal] = mapperRE.exec(formattedValue) ?? [null,null,null];
  //In case the captured position is number it means there's no thousand separator
  if(digitRE.test(thousand)) 
    thousand = '';
  return {thousand, decimal}
}

Upvotes: 1

Luke
Luke

Reputation: 19961

A little further digging and I found Intl.NumberFormat. I think this is more elegant...

const thousandsSeparator = (function(){
    if (typeof Intl !== 'object') {
        return ','; // fallback
    }
    // Get the formatting object for your locale
    const numFormat = new Intl.NumberFormat();
    // The resolved.pattern will be something like "#,##0.###"
    return numFormat.resolved.pattern.substr(1,1);
})();

Or if you really need it ultra-concise...

const thousandsSeparator = (Intl) ? (new Intl.NumberFormat()).resolved.pattern.substr(1,1) : ",";

Compatibility warning (2015):

  • The Intl object may not be supported in Safari for some reason -- http://caniuse.com/#feat=internationalization -- despite it being part of standard ECMAScript.
  • While the Intl object may exist in some ECMAScript-standard browsers, the code above will only work in Chrome.
  • Sadly Firefox 40 and IE 11 currently do not have a resolved property in numFormat.

An elegant cross-browser solution is still out there...

Update (2021):

Intl, and numFormat.resolved may have better browser support in non-Chrome browsers now. See comments for latest information.

Upvotes: 5

Related Questions