Skip to content

Instantly share code, notes, and snippets.

@kawarimidoll
Last active January 19, 2022 04:40
Show Gist options
  • Save kawarimidoll/0ff7517a3c3e4c3ddcd49efd71c3fdb4 to your computer and use it in GitHub Desktop.
Save kawarimidoll/0ff7517a3c3e4c3ddcd49efd71c3fdb4 to your computer and use it in GitHub Desktop.
Number formatter for display in Japanese

jpNumberFormat.js

数値を日本語の文章中で見やすい形式に桁区切りします。

  • 4桁ごとになどの日本語の区切りを挟みます。
    • までしか用意していないので、それより大きな数値は正しく表現できません。
    • 小数点以下はそのまま表示します。
  • 千の桁には,を追加します。
    • これが不要である場合、出力結果に.replaceAll(",", "")を適用することで削除できます。
console.log(jpNumberFormat(0));
// -> 0
console.log(jpNumberFormat(10203));
// -> 1万203
console.log(jpNumberFormat(102030));
// -> 10万2,030
console.log(jpNumberFormat(12345678));
// -> 1,234万5,678
console.log(jpNumberFormat("1000000300"));
// -> 10億300
console.log(jpNumberFormat(Number.MAX_SAFE_INTEGER));
// -> 9,007兆1,992億5,474万991

console.log(jpNumberFormat("00100"));
// -> 100
console.log(jpNumberFormat("-1000"));
// -> -1,000
console.log(jpNumberFormat(20409.43));
// -> 2万409.43
/**
* Format input number with inserting Japanese separators each 4 digits and commas each 3 digits.
* This may works wrong when input number is larger than 32 digits.
* @param {string | number} Input number or string
* @return {string} Formatted string
* @example
* ```js
* console.log(jpNumberFormat(10203)); // -> 1万203
* console.log(jpNumberFormat("12345678")); // -> 1,234万5,678
* console.log(jpNumberFormat(Number.MAX_SAFE_INTEGER)); // -> 9,007兆1,992億5,474万991
* ```
*/
function jpNumberFormat(number = 0) {
return `${number}`.replace(
/0*(\d+)/,
(_, natural) =>
[...natural].reverse().reduce(
(acc, crnt, i) =>
crnt +
((i % 4 === 0) && [..."万億兆京垓𥝱穣"][Math.floor(i / 4) - 1] || "") + acc,
"",
).replace(/(\D)(0+\D?)+/g, "$1").replace(/(\d)(\d{3})/g, "$1,$2"),
);
}
/**
* @deprecated This only works in Number.
*/
function jpNumberFormat(number = 0) {
if (number <= 0) {
return "0";
}
const SEPARATIONS = ["", "万", "億", "兆"];
const DIVIDER = 10000;
function inner(num) {
return num < DIVIDER
? [num]
: [num % DIVIDER, ...inner(Math.floor(num / DIVIDER))];
}
return inner(number).reduce(
(acc, crnt, i) =>
(crnt === 0 ? "" : crnt.toLocaleString("en-US") + SEPARATIONS[i]) + acc,
"",
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment