如何以i18n友好的方式缩写大数字?

时间:2017-01-12 04:08:51

标签: internationalization

我希望使用对于给定语言环境惯用的缩写来“缩写”大数字以使其具有人类可读性。例如,数字16512将成为:

  • "16.5k"代表en-US(“k”是公制前缀“千”的缩写,如“公里”)
  • "16,5тыс."代表ru(“тыс。”是“тысяча”的缩写,意为“千”俄文)

我不确定该怎么称呼这个我正在描述的程序。

Ruby on Rails有类似于我正在寻找的名为#number_to_human的东西,但它不太正确 - 它会在上面的例子中返回"16.5 Thousand"。我对缩写感兴趣(并且可能并非所有语言环境都将事物四舍五入到最接近的千位),而不仅仅是使字符串具有人类可读性。

我对一个适用于JavaScript的解决方案特别感兴趣,但即使这个程序的名称也会有很大的帮助!

1 个答案:

答案 0 :(得分:3)

回答我自己的问题:

我所描述的程序称为紧凑型号格式。有两种变体:"16.5K")和 long "16.5 Thousand")。 Unicode公共区域设置数据存储库(CLDR)为每个区域设置中的压缩数字提供数字格式设置模式:http://cldr.unicode.org/translation/number-patterns#TOC-Short-Numbers

对于JavaScript,有一个(停滞的)ECMA提案,要向compact API添加Intl.NumberFormat选项:https://github.com/tc39/ecma402/issues/37

幸运的是,对于Ruby和JS程序员,Twitter有一个名为twitter_cldr的NPM包(文档是herehere)。用法如下:

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億' ]

请注意,在日本,人们不会说“1230万”,他们会说“1231.2万”。将其添加到程序员假设世界的假名列表中!