381 lines
8.7 KiB
TypeScript
381 lines
8.7 KiB
TypeScript
![]() |
const oneDigit = [
|
|||
|
"صفر",
|
|||
|
"یک",
|
|||
|
"دو",
|
|||
|
"سه",
|
|||
|
"چهار",
|
|||
|
"پنج",
|
|||
|
"شش",
|
|||
|
"هفت",
|
|||
|
"هشت",
|
|||
|
"نه",
|
|||
|
];
|
|||
|
const twoDigits = {
|
|||
|
10: "ده",
|
|||
|
11: "یازده",
|
|||
|
12: "دوازده",
|
|||
|
13: "سیزده",
|
|||
|
14: "چهارده",
|
|||
|
15: "پانزده",
|
|||
|
16: "شانزده",
|
|||
|
17: "هفده",
|
|||
|
18: "هجده",
|
|||
|
19: "نوزده",
|
|||
|
20: "بیست",
|
|||
|
30: "سی",
|
|||
|
40: "چهل",
|
|||
|
50: "پنجاه",
|
|||
|
60: "شصت",
|
|||
|
70: "هفتاد",
|
|||
|
80: "هشتاد",
|
|||
|
90: "نود",
|
|||
|
};
|
|||
|
const threeDigits = {
|
|||
|
100: "صد",
|
|||
|
200: "دویست",
|
|||
|
300: "سیصد",
|
|||
|
400: "چهارصد",
|
|||
|
500: "پانصد",
|
|||
|
600: "شش صد",
|
|||
|
700: "هفت صد",
|
|||
|
800: "هشت صد",
|
|||
|
900: "نه صد",
|
|||
|
};
|
|||
|
|
|||
|
const types = ["تلیارد", "میلیارد", "میلیون", "هزار", ""];
|
|||
|
const decimalTypes = ["دهم", "صدم", "هزارم", "ده هزارم"];
|
|||
|
let numbers = [];
|
|||
|
let decimals = [];
|
|||
|
|
|||
|
//Convert Number To Words
|
|||
|
const convert = (number) => {
|
|||
|
let negative = "";
|
|||
|
let decNumber = "";
|
|||
|
let decimal = "";
|
|||
|
let percent = "";
|
|||
|
|
|||
|
if (isPercent(number)) {
|
|||
|
number = number.replace("%", "");
|
|||
|
percent = " درصد";
|
|||
|
}
|
|||
|
|
|||
|
number = getString(number);
|
|||
|
if (number == "") return "";
|
|||
|
sliceNumber(number);
|
|||
|
if (isNegative(number)) negative = "منفی ";
|
|||
|
number = number.replace("-", "");
|
|||
|
|
|||
|
if (isDecimal(number)) {
|
|||
|
let index = number.indexOf(".");
|
|||
|
let decNumberStr = "";
|
|||
|
|
|||
|
decNumber = number.substr(index + 1, number.length);
|
|||
|
number = number.substr(0, index);
|
|||
|
decNumberStr = parseInt(decNumber).toString();
|
|||
|
|
|||
|
if (decNumberStr.length === 1 && decNumberStr != "0") {
|
|||
|
decimal += oneDigit[decNumberStr] + " ";
|
|||
|
decimal += decimalTypes[decNumber.length - 1];
|
|||
|
} else {
|
|||
|
decimal = calculateDigits(decimals);
|
|||
|
decimal += " " + decimalTypes[decNumber.length - 1];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (number.length === 1) {
|
|||
|
if (!decimal) {
|
|||
|
return negative + oneDigit[number] + percent;
|
|||
|
}
|
|||
|
|
|||
|
if (number == "0") {
|
|||
|
return negative + decimal + percent;
|
|||
|
}
|
|||
|
|
|||
|
return negative + oneDigit[number] + " ممیز " + decimal + percent;
|
|||
|
}
|
|||
|
|
|||
|
if (!decimal) {
|
|||
|
return negative + calculateDigits(numbers) + percent;
|
|||
|
}
|
|||
|
|
|||
|
return negative + calculateDigits(numbers) + " ممیز " + decimal + percent;
|
|||
|
};
|
|||
|
|
|||
|
//split number 3 by 3 with a separator (123456789.3025=>123,456,789.3,025) Do Not Give It Persian Numbers
|
|||
|
const sliceNumber = (number, separator = ",") => {
|
|||
|
let percent = "";
|
|||
|
let neg = "";
|
|||
|
let dNum = "";
|
|||
|
let n = "";
|
|||
|
let d = "";
|
|||
|
|
|||
|
if (isPercent(number)) {
|
|||
|
number = number.replace("%", "");
|
|||
|
percent = "%";
|
|||
|
}
|
|||
|
|
|||
|
number = getString(number);
|
|||
|
|
|||
|
if (number == "") return "";
|
|||
|
if (isNegative(number)) neg = "-";
|
|||
|
|
|||
|
number = number.replace("-", "");
|
|||
|
|
|||
|
if (isDecimal(number)) {
|
|||
|
let index = number.indexOf(".");
|
|||
|
dNum = number.substr(index + 1, number.length);
|
|||
|
number = number.substr(0, index);
|
|||
|
}
|
|||
|
|
|||
|
n = putSeparator(number, separator);
|
|||
|
numbers = n.split(separator);
|
|||
|
|
|||
|
if (!dNum) return neg + n + percent;
|
|||
|
|
|||
|
d = putSeparator(dNum, separator);
|
|||
|
decimals = d.split(separator);
|
|||
|
|
|||
|
return neg + n + "." + d + percent;
|
|||
|
};
|
|||
|
|
|||
|
//Puts a separator between the chunks of the given numString.
|
|||
|
const putSeparator = (numString, separator = ",") => {
|
|||
|
if (typeof numString !== "string") return "";
|
|||
|
if (numString.length < 4) return numString;
|
|||
|
|
|||
|
let result = "";
|
|||
|
for (let i = numString.length - 1, counter = 0; i >= 0; i--) {
|
|||
|
if (counter == 3) {
|
|||
|
result += separator;
|
|||
|
counter = 0;
|
|||
|
}
|
|||
|
result += numString[i];
|
|||
|
counter++;
|
|||
|
}
|
|||
|
|
|||
|
result = result.split("").reverse().join("");
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
//Processing on Digits of A Number
|
|||
|
const calculateDigits = (arrNum) => {
|
|||
|
let result = "";
|
|||
|
for (let i = 0; i < arrNum.length; i++) {
|
|||
|
let parsedNum = parseInt(arrNum[i]);
|
|||
|
let number = parsedNum;
|
|||
|
let sadgan = Math.floor(number / 100) * 100;
|
|||
|
number = number % 100;
|
|||
|
let dahgan = Math.floor(number / 10) * 10;
|
|||
|
let yekan = number % 10;
|
|||
|
result += i !== 0 && parsedNum ? " و " : "";
|
|||
|
|
|||
|
result +=
|
|||
|
getPersian(sadgan, dahgan, yekan, i, arrNum) + " " + getType(i, arrNum);
|
|||
|
}
|
|||
|
|
|||
|
return result.trim();
|
|||
|
};
|
|||
|
|
|||
|
//Main Process That Turn a Number Into a String(122=>100+20+2)
|
|||
|
const getPersian = (sadgan, dahgan, yekan, index, numbers) => {
|
|||
|
let flag = false;
|
|||
|
let result = "";
|
|||
|
let dahganPlusYekan = dahgan + yekan;
|
|||
|
|
|||
|
if (threeDigits[sadgan]) {
|
|||
|
result +=
|
|||
|
yekan > 0 || dahgan > 0
|
|||
|
? threeDigits[sadgan] + " و "
|
|||
|
: threeDigits[sadgan];
|
|||
|
}
|
|||
|
|
|||
|
if (twoDigits[dahganPlusYekan]) {
|
|||
|
result += twoDigits[dahganPlusYekan] + " ";
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
if (twoDigits[dahgan]) {
|
|||
|
result += twoDigits[dahgan] + " و ";
|
|||
|
}
|
|||
|
|
|||
|
if (
|
|||
|
numbers.length === 2 &&
|
|||
|
index === 0 &&
|
|||
|
yekan === 1 &&
|
|||
|
dahgan === 0 &&
|
|||
|
sadgan === 0
|
|||
|
) {
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
if (
|
|||
|
numbers.length > 2 &&
|
|||
|
index === numbers.length - 2 &&
|
|||
|
yekan === 1 &&
|
|||
|
dahgan === 0 &&
|
|||
|
sadgan === 0
|
|||
|
) {
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
if (yekan > 0) result += oneDigit[yekan] + " ";
|
|||
|
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
//getting The Type Of Each Number (Billion, Million,...)
|
|||
|
const getType = (i, numbers) => {
|
|||
|
let parsedNum = parseInt(numbers[i]);
|
|||
|
if (isNaN(parsedNum)) return "";
|
|||
|
if (!parsedNum) return "";
|
|||
|
let length = numbers.length - i;
|
|||
|
let index = types.length - length;
|
|||
|
return types[index];
|
|||
|
};
|
|||
|
|
|||
|
//Calculate if number:String is Negative Or Not
|
|||
|
const isNegative = (number) => {
|
|||
|
number = getString(number);
|
|||
|
if (!number) return false;
|
|||
|
if (number[0] != "-") return false;
|
|||
|
number = number.replace("-", "");
|
|||
|
return number != "0";
|
|||
|
};
|
|||
|
|
|||
|
//Calculate if number:String has '%' as Percent
|
|||
|
const isPercent = (string) => {
|
|||
|
if (typeof string !== "string") return false;
|
|||
|
let index = string.indexOf("%");
|
|||
|
let lIndex = string.lastIndexOf("%");
|
|||
|
if (index != lIndex) return false;
|
|||
|
return index > 0;
|
|||
|
};
|
|||
|
|
|||
|
//is number:String:Number is a Valid Number? if type is Number turn it to String And Return it
|
|||
|
const getString = (number) => {
|
|||
|
if (number === undefined) return "";
|
|||
|
if (number === null) return "";
|
|||
|
if (isNaN(number)) return "";
|
|||
|
if (typeof number === "number") return number.toString();
|
|||
|
return number.trim();
|
|||
|
};
|
|||
|
|
|||
|
//Calculate if number:String has Decimal Point Or Not
|
|||
|
const isDecimal = (number) => {
|
|||
|
number = getString(number);
|
|||
|
if (number == "") return false;
|
|||
|
let index = number.indexOf(".");
|
|||
|
let lIndex = number.lastIndexOf(".");
|
|||
|
if (index != lIndex) return false;
|
|||
|
return index > 0;
|
|||
|
};
|
|||
|
//Convert English Numbers To Persian Numbers
|
|||
|
const convertEnToPe = (number) => {
|
|||
|
if (number == null || number == undefined) return "";
|
|||
|
if (typeof number == "number") number = number.toString();
|
|||
|
let res = "";
|
|||
|
for (let i = 0; i < number.length; i++) {
|
|||
|
switch (number[i]) {
|
|||
|
case "\u0030":
|
|||
|
res += "\u06F0";
|
|||
|
break;
|
|||
|
case "\u0031":
|
|||
|
res += "\u06F1";
|
|||
|
break;
|
|||
|
case "\u0032":
|
|||
|
res += "\u06F2";
|
|||
|
break;
|
|||
|
case "\u0033":
|
|||
|
res += "\u06F3";
|
|||
|
break;
|
|||
|
case "\u0034":
|
|||
|
res += "\u06F4";
|
|||
|
break;
|
|||
|
case "\u0035":
|
|||
|
res += "\u06F5";
|
|||
|
break;
|
|||
|
case "\u0036":
|
|||
|
res += "\u06F6";
|
|||
|
break;
|
|||
|
case "\u0037":
|
|||
|
res += "\u06F7";
|
|||
|
break;
|
|||
|
case "\u0038":
|
|||
|
res += "\u06F8";
|
|||
|
break;
|
|||
|
case "\u0039":
|
|||
|
res += "\u06F9";
|
|||
|
break;
|
|||
|
default:
|
|||
|
res += number[i];
|
|||
|
}
|
|||
|
}
|
|||
|
return res;
|
|||
|
};
|
|||
|
//Convert Persian Numbers To English Numbers
|
|||
|
const convertPeToEn = (number) => {
|
|||
|
if (number == null || number == undefined) return "";
|
|||
|
let res = "";
|
|||
|
for (let i = 0; i < number.length; i++) {
|
|||
|
switch (number[i]) {
|
|||
|
case "\u06F0":
|
|||
|
res += "\u0030";
|
|||
|
break;
|
|||
|
case "\u06F1":
|
|||
|
res += "\u0031";
|
|||
|
break;
|
|||
|
case "\u06F2":
|
|||
|
res += "\u0032";
|
|||
|
break;
|
|||
|
case "\u06F3":
|
|||
|
res += "\u0033";
|
|||
|
break;
|
|||
|
case "\u06F4":
|
|||
|
res += "\u0034";
|
|||
|
break;
|
|||
|
case "\u06F5":
|
|||
|
res += "\u0035";
|
|||
|
break;
|
|||
|
case "\u06F6":
|
|||
|
res += "\u0036";
|
|||
|
break;
|
|||
|
case "\u06F7":
|
|||
|
res += "\u0037";
|
|||
|
break;
|
|||
|
case "\u06F8":
|
|||
|
res += "\u0038";
|
|||
|
break;
|
|||
|
case "\u06F9":
|
|||
|
res += "\u0039";
|
|||
|
break;
|
|||
|
default:
|
|||
|
res += number[i];
|
|||
|
}
|
|||
|
}
|
|||
|
return res;
|
|||
|
};
|
|||
|
|
|||
|
const e2p = (s) => s.replace(/\d/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[d]);
|
|||
|
const e2a = (s) => s.replace(/\d/g, (d) => "٠١٢٣٤٥٦٧٨٩"[d]);
|
|||
|
|
|||
|
const p2e = (s) => s.replace(/[۰-۹]/g, (d) => "۰۱۲۳۴۵۶۷۸۹".indexOf(d));
|
|||
|
const a2e = (s) => s.replace(/[٠-٩]/g, (d) => "٠١٢٣٤٥٦٧٨٩".indexOf(d));
|
|||
|
|
|||
|
const p2a = (s) =>
|
|||
|
s.replace(/[۰-۹]/g, (d) => "٠١٢٣٤٥٦٧٨٩"["۰۱۲۳۴۵۶۷۸۹".indexOf(d)]);
|
|||
|
const a2p = (s) =>
|
|||
|
s.replace(/[٠-٩]/g, (d) => "۰۱۲۳۴۵۶۷۸۹"["٠١٢٣٤٥٦٧٨٩".indexOf(d)]);
|
|||
|
|
|||
|
export {
|
|||
|
convert,
|
|||
|
sliceNumber,
|
|||
|
convertEnToPe,
|
|||
|
convertPeToEn,
|
|||
|
e2p,
|
|||
|
e2a,
|
|||
|
p2e,
|
|||
|
a2e,
|
|||
|
p2a,
|
|||
|
a2p,
|
|||
|
};
|