UNPKG

amount-to-words-multilang

Version:

Convert numbers to words in multiple languages (EN, TH, FR, JA, DE, ET, ES, FA, ZH)

136 lines (135 loc) 4.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PersianConverter = void 0; /** * Persian (Farsi) Number to Words Converter * * Features: * - Persian number system with proper script * - Currency: Euro and سنت (euro and sent) * - Right-to-left reading support * - Persian digits and compound number formation * - Handles traditional Persian number naming */ class PersianConverter { constructor() { this.ones = [ '', 'یک', 'دو', 'سه', 'چهار', 'پنج', 'شش', 'هفت', 'هشت', 'نه', 'ده', 'یازده', 'دوازده', 'سیزده', 'چهارده', 'پانزده', 'شانزده', 'هفده', 'هجده', 'نوزده' ]; this.tens = [ '', '', 'بیست', 'سی', 'چهل', 'پنجاه', 'شصت', 'هفتاد', 'هشتاد', 'نود' ]; this.hundreds = [ '', 'یکصد', 'دویست', 'سیصد', 'چهارصد', 'پانصد', 'ششصد', 'هفتصد', 'هشتصد', 'نهصد' ]; this.scales = [ { value: 1000000000, name: 'میلیارد' }, { value: 1000000, name: 'میلیون' }, { value: 1000, name: 'هزار' } ]; } convert(amount) { if (!this.isValidNumber(amount)) { throw new Error('Amount must be a non-negative finite number'); } if (amount > 999999999999.99) { throw new Error('Amount too large'); } const [wholePart, decimalPart] = this.parseAmount(amount); let result = ''; if (wholePart === 0) { result = 'صفر یورو'; } else { const wholeWords = this.convertWholeNumber(wholePart); result = `${wholeWords} یورو`; } if (decimalPart > 0) { const centWords = this.convertWholeNumber(decimalPart); result += ` ${centWords} سنت`; } return result; } isValidNumber(num) { return typeof num === 'number' && isFinite(num) && num >= 0; } parseAmount(amount) { // Handle floating point precision by using string manipulation const amountStr = amount.toFixed(3); const [wholeStr, decimalStr = '0'] = amountStr.split('.'); const wholePart = parseInt(wholeStr, 10); const decimalPart = parseInt(decimalStr.substring(0, 2).padEnd(2, '0'), 10); return [wholePart, decimalPart]; } convertWholeNumber(num) { if (num === 0) return ''; if (num < 20) return this.ones[num]; if (num < 100) return this.convertTens(num); if (num < 1000) return this.convertHundreds(num); for (const scale of this.scales) { if (num >= scale.value) { return this.convertScale(num, scale); } } return ''; } convertTens(num) { const ten = Math.floor(num / 10); const one = num % 10; if (one === 0) { return this.tens[ten]; } return `${this.tens[ten]} و ${this.ones[one]}`; } convertHundreds(num) { const hundred = Math.floor(num / 100); const remainder = num % 100; let result = this.hundreds[hundred]; if (remainder > 0) { if (remainder < 20) { result += ` و ${this.ones[remainder]}`; } else { result += ` و ${this.convertTens(remainder)}`; } } return result; } convertScale(num, scale) { const quotient = Math.floor(num / scale.value); const remainder = num % scale.value; let result = ''; if (scale.value === 1000) { // Special handling for thousands - Persian rule for 1000 vs 1000+ if (quotient === 1) { // For exact 1000 and 1001-1099, use "هزار" // For 1100+ (when remainder has hundreds), use "یک هزار" if (remainder === 0 || remainder < 100) { result = 'هزار'; } else { result = 'یک هزار'; } } else { result = `${this.convertWholeNumber(quotient)} هزار`; } } else { // Millions and billions result = `${this.convertWholeNumber(quotient)} ${scale.name}`; } if (remainder > 0) { result += ` و ${this.convertWholeNumber(remainder)}`; } return result; } } exports.PersianConverter = PersianConverter;