ucarion
ucarion

Reputation: 751

How to abbreviate large numbers in a i18n-friendly way?

I want to "abbreviate" large numbers to make them human-readable, using abbreviations that are idiomatic for a given locale. For example, the number 16512 would become:

I'm not sure what to call this procedure I'm describing.

Ruby on Rails has something similar to what I'm looking for called #number_to_human, but it's not quite right -- it would return "16.5 Thousand" in my example above. I'm interested in abbreviations (and perhaps not all locales round things to the nearest thousand), not merely making strings human-readable.

I'd be especially interested in a solution that works for JavaScript, but even the name of this procedure would be a huge help!

Upvotes: 7

Views: 2709

Answers (1)

ucarion
ucarion

Reputation: 751

Answering my own question:

The procedure I'm describing is known as compact number formatting. There are two variants: short ("16.5K") and long ("16.5 Thousand"). The Unicode Common Locale Data Repository (CLDR) provides number-formatting patterns for compact numbers in each locale: http://cldr.unicode.org/translation/number-patterns#TOC-Short-Numbers

For JavaScript, there is a (stalled) ECMA proposal to add a compact option to the Intl.NumberFormat API: https://github.com/tc39/ecma402/issues/37

Luckily for Ruby and JS programmers, Twitter has an NPM package called twitter_cldr (documentation is here and here). Usage looks like this:

const TwitterCldr = require('twitter_cldr');

function printNumbers(localeName) {
    const locale = TwitterCldr.load(localeName);
    const formatter = new locale.ShortDecimalFormatter();

    const numbers = [123, 1231, 12312, 123123, 1231231, 12312312, 123123123];
    return numbers.map(n => formatter.format(n, { precision: 1 }));
}

console.log(printNumbers('en'));
// [ '123.0', '1.2K', '12.3K', '123.1K', '1.2M', '12.3M', '123.1M' ]
console.log(printNumbers('ru'));
// [ '123,0', '1,2 тыс.', '12,3 тыс.', '123,1 тыс.', '1,2 млн', '12,3 млн', 123,1 млн' ]
console.log(printNumbers('ja'));
// [ '123.0', '1.2千', '1.2万', '12.3万', '123.1万', '1231.2万', '1.2億' ]

Note that in Japan, people wouldn't say "12.3 Million", they'd say "1231.2 Ten-Thousand". Add that to the list of falsehoods programmers assume about the world!

Upvotes: 10

Related Questions