Last active
September 27, 2021 09:08
-
-
Save vanduc1102/42a50017891983d0190ff32f9e936ff7 to your computer and use it in GitHub Desktop.
Number to Text , Vietnamese and English only. Origin Post https://www.kimkha.com/2010/03/giai-thuat-oi-tu-so-sang-chu-tieng-viet.html and https://stackoverflow.com/questions/5529934/javascript-numbers-to-words
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const NUMERALS = [ | |
{ value: 1000000000000000000000, str: 'sextillion' }, | |
{ value: 1000000000000000000, str: 'quintillion' }, | |
{ value: 1000000000000000, str: 'quadrillion' }, | |
{ value: 1000000000000, str: 'trillion' }, | |
{ value: 1000000000, str: 'billion' }, | |
{ value: 1000000, str: 'million' }, | |
{ value: 1000, str: 'thousand' }, | |
{ value: 100, str: 'hundred' }, | |
{ value: 90, str: 'ninety' }, | |
{ value: 80, str: 'eighty' }, | |
{ value: 70, str: 'seventy' }, | |
{ value: 60, str: 'sixty' }, | |
{ value: 50, str: 'fifty' }, | |
{ value: 40, str: 'forty' }, | |
{ value: 30, str: 'thirty' }, | |
{ value: 20, str: 'twenty' }, | |
{ value: 19, str: 'nineteen' }, | |
{ value: 18, str: 'eighteen' }, | |
{ value: 17, str: 'seventeen' }, | |
{ value: 16, str: 'sixteen' }, | |
{ value: 15, str: 'fifteen' }, | |
{ value: 14, str: 'fourteen' }, | |
{ value: 13, str: 'thirteen' }, | |
{ value: 12, str: 'twelve' }, | |
{ value: 11, str: 'eleven' }, | |
{ value: 10, str: 'ten' }, | |
{ value: 9, str: 'nine' }, | |
{ value: 8, str: 'eight' }, | |
{ value: 7, str: 'seven' }, | |
{ value: 6, str: 'six' }, | |
{ value: 5, str: 'five' }, | |
{ value: 4, str: 'four' }, | |
{ value: 3, str: 'three' }, | |
{ value: 2, str: 'two' }, | |
{ value: 1, str: 'one' }, | |
]; | |
function convertEnglish(n: number): string { | |
if (n < 0) { | |
return `minus ${convertEnglish(-n)}`; | |
} else if (n === 0) { | |
return 'zero'; | |
} else { | |
let result = ''; | |
for (const numeral of NUMERALS) { | |
if (n >= numeral.value) { | |
if (n < 100) { | |
result += numeral.str; | |
n -= numeral.value; | |
if (n > 0) result += '-'; | |
} else { | |
const times = Math.floor(n / numeral.value); | |
result += `${convertEnglish(times)} ${numeral.str}`; | |
n -= numeral.value * times; | |
if (n > 0) result += ' and '; | |
} | |
} | |
} | |
return result; | |
} | |
} | |
const WORD_NUMBERS = [ | |
'không', | |
'một', | |
'hai', | |
'ba', | |
'bốn', | |
'năm', | |
'sáu', | |
'bảy', | |
'tám', | |
'chín', | |
]; | |
function readDozen(no: number, isWhole: boolean) { | |
let dozen = ''; | |
const quotient = Math.floor(no / 10); | |
const remainder = no % 10; | |
if (quotient > 1) { | |
dozen = ` ${WORD_NUMBERS[quotient]} mươi`; | |
if (remainder === 1) { | |
dozen += ' mốt'; | |
} | |
} else if (quotient === 1) { | |
dozen = ' mười'; | |
if (remainder === 1) { | |
dozen += ' một'; | |
} | |
} else if (isWhole && remainder > 0) { | |
dozen = ' lẻ'; | |
} | |
if (remainder === 5 && quotient > 1) { | |
dozen += ' lăm'; | |
} else if (remainder > 1 || (remainder === 1 && quotient === 0)) { | |
dozen += ` ${WORD_NUMBERS[remainder]}`; | |
} | |
return dozen; | |
} | |
function readHundred(no: number, isWhole: boolean) { | |
let text = ''; | |
const tram = Math.floor(no / 100); | |
no = no % 100; | |
if (isWhole || tram > 0) { | |
text = ` ${WORD_NUMBERS[tram]} trăm`; | |
text += readDozen(no, true); | |
} else { | |
text = readDozen(no, false); | |
} | |
return text; | |
} | |
function readMillion(no: number, isWhole: boolean) { | |
let text = ''; | |
const million = Math.floor(no / 1000000); | |
no = no % 1000000; | |
if (million > 0) { | |
text = `${readHundred(million, isWhole)} triệu`; | |
isWhole = true; | |
} | |
const thousand = Math.floor(no / 1000); | |
no = no % 1000; | |
if (thousand > 0) { | |
text += `${readHundred(thousand, isWhole)} nghìn`; | |
isWhole = true; | |
} | |
if (no > 0) { | |
text += readHundred(no, isWhole); | |
} | |
return text; | |
} | |
function convertVietnamese(no: number) { | |
if (no === 0) return WORD_NUMBERS[0]; | |
let text = '', | |
postFix = ''; | |
do { | |
const billion = no % 1000000000; | |
no = Math.floor(no / 1000000000); | |
if (no > 0) { | |
text = readMillion(billion, true) + postFix + text; | |
} else { | |
text = readMillion(billion, false) + postFix + text; | |
} | |
postFix = ' tỷ'; | |
} while (no > 0); | |
return text; | |
} | |
export function convertToText(n: number): string { | |
const code = localStorage.getItem('i18nextLng'); | |
if (code === 'vi') { | |
return convertVietnamese(n).trim(); | |
} | |
return convertEnglish(n); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment