indian_formatters
A comprehensive Flutter/Dart package for India-specific formatting, validation, and parsing. Now with tree-shaking support, deep checksum validation, and reverse parsing!
What's New in v0.0.2 🚀
🌳 Tree-Shaking Support - Reduce your bundle size by up to 80%!
// 🌳 Granular imports for optimal tree-shaking (up to 80% smaller bundle!)
import 'package:indian_formatters/validators/upi.dart';
import 'package:indian_formatters/validators/pan.dart';
// Only UPI and PAN validators included - everything else tree-shaken away!
📍 Pincode Mapper - Accurate state detection using official India Post logic
// 📍 Pincode mapping with first 2-digit logic
String state = PincodeMapper.getState('411001'); // "Maharashtra"
String region = PincodeMapper.getRegionName('411001'); // "Pune Region"
bool isUT = PincodeMapper.isUnionTerritory('110001'); // true (Delhi)
🔐 Deep Checksum Validation - Mathematical validation for PAN and GST
// 🔐 Deep mathematical checksum validation
bool isValid = PANValidator.isPAN('ABCDE1234F'); // Validates 10th character checksum
String checksum = PANValidator.calculateChecksum('ABCDE1234'); // Calculate checksum
String pan = GSTValidator.extractPAN('27AAPFU0939F1ZV'); // Extract PAN from GST
🔄 Reverse Parsing - Parse formatted strings back to numbers
// 🔄 Reverse parsing back to raw numbers
num value = "12,34,567".parseIndianNumber(); // 1234567
num compactValue = "12L".parseIndianCompact(); // 1200000
num currency = "₹12,34,567.89".parseIndianCurrency(); // 1234567.89
List<num> range = "1L - 5L".parseIndianRange(); // [100000, 500000]
Features
✨ Number Formatting
- Indian numbering system (lakhs, crores, arabs)
- Number to words (English and Hindi)
- Compact notation (12L, 1Cr)
- NEW: Reverse parsing from formatted strings
💰 Currency Formatting
- ₹ symbol with Indian comma grouping
- Amount in words (for cheques)
- Compact currency notation
- NEW: Parse currency strings back to numbers
✅ Validators
- NEW: Tree-shaking support - import only what you need!
- NEW: Deep mathematical checksum validation for PAN & GST
- PAN Card (with holder type detection + checksum validation)
- Aadhaar (with Verhoeff algorithm)
- GST Number (with state extraction + checksum validation)
- Mobile Number (with operator detection)
- IFSC Code (with bank name)
- PIN Code (NEW: accurate state/region mapping)
- Driving License
- Voter ID (EPIC)
- UPI ID (with provider detection)
📅 Date Formatting
- Indian date format
- Hindi numerals and month names
- Fiscal year and financial quarter
- Hindu calendar month names
🗺️ Address Utilities
- All 28 states + 8 UTs
- GST codes, capitals, Hindi names
- Address formatting with copyWith support
- NEW: Pincode to state/region mapping with 70+ regions
🌳 Tree-Shaking & Bundle Optimization
- NEW: Granular imports reduce bundle size by up to 80%
- Import only validators, only formatters, or individual components
- Zero bloat - only include what you use
Installation
Add this to your pubspec.yaml:
dependencies:
indian_formatters: ^0.0.2
Or install via command line:
flutter pub add indian_formatters
Quick Start
// 🌳 Tree-shaking imports (recommended for smaller bundle size)
import 'package:indian_formatters/validators/pan.dart';
import 'package:indian_formatters/validators/upi.dart';
import 'package:indian_formatters/formatters.dart';
// OR full import (convenience)
import 'package:indian_formatters/indian_formatters.dart';
// Number formatting
print(1234567.toIndian()); // "12,34,567"
print(1234567.toIndianWords()); // "12 Lakh 34 Thousand 5 Hundred 67"
print(1234567.toIndianWordsHindi()); // "बारह लाख चौंतीस हज़ार..."
print(1200000.toIndianCompact()); // "12L"
// 🔄 NEW: Reverse parsing
print("12,34,567".parseIndianNumber()); // 1234567
print("12L".parseIndianCompact()); // 1200000
print("₹12,34,567.89".parseIndianCurrency()); // 1234567.89
// Currency formatting
print(1234567.89.toRupees()); // "₹12,34,567.89"
print(1234567.89.toRupeesWords()); // "Twelve Lakh... Rupees and Eighty-Nine Paise"
print(1234567.89.toChequeFormat()); // "... Rupees and Eighty-Nine Paise Only"
// 🔐 NEW: Enhanced validators with checksum validation
print(PANValidator.isPAN("ABCDE1234F")); // true (with checksum validation)
print(GSTValidator.isGST("27AAPFU0939F1ZV")); // true (with checksum validation)
print(IndianValidators.validateAadhaar("234567890123")); // null (valid)
// 📍 NEW: Accurate pincode mapping
print(PincodeMapper.getState("411001")); // "Maharashtra"
print(PincodeMapper.getRegionName("411001")); // "Pune Region"
print(PincodeMapper.isUnionTerritory("110001")); // true (Delhi)
// Date formatting
print(DateTime.now().toIndianFormat()); // "24 April 2026"
print(DateTime.now().fiscalYear()); // "FY 2026-27"
print(DateTime.now().financialQuarter()); // "Q1 FY27"
// States and address
final mh = IndianStates.byCode("MH");
print(mh?.gstCode); // 27
print(mh?.capital); // "Mumbai"
🌳 Tree-Shaking & Import Strategies
Optimize your bundle size with granular imports!
Option 1: Full Import (Convenience)
import 'package:indian_formatters/indian_formatters.dart';
// Everything included - formatters, validators, utilities
Option 2: Validators Only (~40% smaller)
import 'package:indian_formatters/validators.dart';
// Only validators - formatters tree-shaken away
Option 3: Formatters Only (~35% smaller)
import 'package:indian_formatters/formatters.dart';
// Only formatters - validators tree-shaken away
Option 4: Individual Imports (~70-80% smaller)
import 'package:indian_formatters/validators/pan.dart';
import 'package:indian_formatters/validators/upi.dart';
// Only PAN and UPI validators - everything else tree-shaken away!
Available Individual Imports:
validators/pan.dart- PAN validation with checksumvalidators/aadhaar.dart- Aadhaar with Verhoeff algorithmvalidators/gst.dart- GST validation with checksumvalidators/upi.dart- UPI ID validationvalidators/mobile.dart- Mobile number validationvalidators/ifsc.dart- IFSC code validationvalidators/pincode.dart- PIN code validationvalidators/driving_license.dart- Driving license validationvalidators/voter_id.dart- Voter ID validation
API Reference
Number Formatting
IndianNumberFormatter
// Static methods
IndianNumberFormatter.format(1234567) // "12,34,567"
IndianNumberFormatter.formatWords(1234567) // "12 Lakh 34 Thousand..."
IndianNumberFormatter.formatWordsHindi(1234567) // "बारह लाख..."
IndianNumberFormatter.toWords(100) // "One Hundred"
IndianNumberFormatter.compact(1200000) // "12L"
IndianNumberFormatter.compactFull(1200000) // "12 Lakh"
IndianNumberFormatter.compactCrore(10000000) // "1Cr"
Extension on num
1234567.toIndian() // "12,34,567"
1234567.toIndianWords() // "12 Lakh 34 Thousand..."
1234567.toIndianWordsHindi() // "बारह लाख..."
1234567.toIndianCompact() // "12L"
1234567.toIndianCompactFull() // "12 Lakh"
100.toWords() // "One Hundred"
100.toWordsHindi() // "एक सौ"
Currency Formatting
IndianCurrencyFormatter
IndianCurrencyFormatter.format(1234567.89) // "₹12,34,567.89"
IndianCurrencyFormatter.format(1234567, symbol: 'Rs. ') // "Rs. 12,34,567"
IndianCurrencyFormatter.formatWords(1234567.89) // "Twelve Lakh... Rupees and Eighty-Nine Paise"
IndianCurrencyFormatter.formatCompact(1234567) // "₹12L"
IndianCurrencyFormatter.forCheque(1234567.89) // "... Rupees and Eighty-Nine Paise Only"
IndianCurrencyFormatter.parseCurrency("₹12,34,567") // 1234567.0
Extension on num
1234567.89.toRupees() // "₹12,34,567.89"
1234567.89.toRupeesWords() // "Twelve Lakh... Rupees and Eighty-Nine Paise"
1234567.toRupeesCompact() // "₹12L"
1234567.89.toChequeFormat() // "... Rupees and Eighty-Nine Paise Only"
🔄 String Parsing (NEW in v0.0.2)
IndianStringParser
// Parse various Indian number formats back to numbers
IndianStringParser.parseNumber("12,34,567") // 1234567
IndianStringParser.parseCurrency("₹12,34,567.89") // 1234567.89
IndianStringParser.parseInt("12,34,567") // 1234567
IndianStringParser.parseCompact("12L") // 1200000
IndianStringParser.parseAny("₹12L") // 1200000
IndianStringParser.canParse("12,34,567") // true
IndianStringParser.parseRange("1L - 5L") // [100000, 500000]
Extension on String
"12,34,567".parseIndianNumber() // 1234567
"₹12,34,567.89".parseIndianCurrency() // 1234567.89
"12,34,567".parseIndianInt() // 1234567
"12L".parseIndianCompact() // 1200000
"₹12L".parseIndianAny() // 1200000
"12,34,567".canParseIndian() // true
"1L - 5L".parseIndianRange() // [100000, 500000]
Supported Formats:
- Indian comma grouping:
"12,34,567"→1234567 - Currency symbols:
"₹12,34,567.89","Rs 1234"→ numbers - Compact notation:
"12L","1.5Cr","50K"→ full numbers - Negative numbers:
"-12,34,567"→-1234567 - Ranges:
"10,000 - 50,000"→[10000, 50000]
Validators
IndianValidators
All validators provide two methods:
isX()→ returnsboolvalidateX()→ returnsString?(null = valid, string = error message)
PAN Card (🔐 NEW: Deep checksum validation)
PANValidator.isPAN("ABCPE1234F") // true (validates 10th character checksum)
PANValidator.isPAN("ABCPE1234F", verifyChecksum: false) // Skip checksum validation
IndianValidators.validatePAN("ABCPE1234F") // null (valid)
IndianValidators.getPANType("ABCPE1234F") // PANType.individual
// NEW: Checksum utilities
PANValidator.calculateChecksum("ABCPE1234") // Returns calculated checksum character
IndianValidators.calculatePANChecksum("ABCPE1234") // Same via IndianValidators
Aadhaar
IndianValidators.isAadhaar("234567890123") // true (with Verhoeff validation)
IndianValidators.validateAadhaar("234567...") // null or error
IndianValidators.maskAadhaar("234567890123") // "XXXX XXXX 0123"
GST Number (🔐 NEW: Deep checksum validation)
GSTValidator.isGST("27AAPFU0939F1ZV") // true (validates 15th character checksum)
GSTValidator.isGST("27AAPFU0939F1ZV", verifyChecksum: false) // Skip checksum validation
IndianValidators.validateGST("27AAPFU0939F1ZV") // null
IndianValidators.getGSTState("27AAPFU0939F1ZV") // "Maharashtra"
IndianValidators.getGSTStateCode("27...") // 27
// NEW: Checksum and PAN extraction utilities
GSTValidator.calculateChecksum("27AAPFU0939F1Z") // Returns calculated checksum character
GSTValidator.extractPAN("27AAPFU0939F1ZV") // "AAPFU0939F"
IndianValidators.calculateGSTChecksum("27AAPFU0939F1Z") // Same via IndianValidators
IndianValidators.extractPANFromGST("27AAPFU0939F1ZV") // Same via IndianValidators
Mobile Number
IndianValidators.isMobile("9876543210") // true
IndianValidators.isMobile("+919876543210") // true
IndianValidators.validateMobile("9876543210") // null
IndianValidators.formatMobile("9876543210") // "+91 98765 43210"
IndianValidators.getOperatorSeries("9876543210") // "Airtel (approx)"
IFSC Code
IndianValidators.isIFSC("SBIN0001234") // true
IndianValidators.validateIFSC("SBIN0001234") // null
IndianValidators.getBankFromIFSC("SBIN0001234") // "State Bank of India"
PIN Code (📍 NEW: Accurate state/region mapping)
IndianValidators.isPincode("411001") // true
IndianValidators.validatePincode("411001") // null
// NEW: Enhanced pincode mapping
PincodeMapper.getState("411001") // "Maharashtra" (accurate)
PincodeMapper.getRegionName("411001") // "Pune Region"
PincodeMapper.getRegion("411001") // PostalRegion object
PincodeMapper.isUnionTerritory("110001") // true (Delhi)
PincodeMapper.searchByState("Maharashtra") // List<PostalRegion>
// Legacy method (less accurate)
IndianValidators.getStateFromPincode("411001") // "Maharashtra, Goa..." (approximate)
Driving License
IndianValidators.isDrivingLicense("MH01-2023-0012345") // true
IndianValidators.validateDrivingLicense("MH01...") // null
Voter ID
IndianValidators.isVoterID("ABC1234567") // true
IndianValidators.validateVoterID("ABC1234567") // null
UPI ID
IndianValidators.isUPI("someone@upi") // true
IndianValidators.validateUPI("someone@upi") // null
IndianValidators.getUPIProvider("someone@okaxis") // "Axis Bank"
Date Formatting
IndianDateFormatter
IndianDateFormatter.format(DateTime.now()) // "16 April 2026"
IndianDateFormatter.formatHindi(DateTime.now()) // "१६ अप्रैल २०२६"
IndianDateFormatter.toHindiNumerals("2026") // "२०२६"
IndianDateFormatter.toDevanagari(DateTime.now()) // "१६/०४/२०२६"
IndianDateFormatter.fiscalYear(DateTime.now()) // "FY 2025-26"
IndianDateFormatter.financialQuarter(DateTime.now()) // "Q1 FY26"
IndianDateFormatter.hinduMonthName(DateTime.now()) // "Chaitra"
IndianDateFormatter.hindiMonthName(DateTime.now()) // "अप्रैल"
Extension on DateTime
DateTime.now().toIndianFormat() // "16 April 2026"
DateTime.now().toHindiFormat() // "१६ अप्रैल २०२६"
DateTime.now().fiscalYear() // "FY 2025-26"
DateTime.now().financialQuarter() // "Q1 FY27"
DateTime.now().hinduMonthName() // "Chaitra"
Address & States
IndianStates
IndianStates.all // List of all 36 states/UTs
IndianStates.byCode("MH") // IndianState object
IndianStates.byGSTCode(27) // IndianState object
IndianStates.search("maha") // [Maharashtra]
// IndianState properties
state.name // "Maharashtra"
state.code // "MH"
state.gstCode // 27
state.capital // "Mumbai"
state.isUT // false
state.hindiName // "महाराष्ट्र"
IndianAddressFormatter
final address = IndianAddressFormatter.format(
line1: "123 Main St",
line2: "Koregaon Park",
city: "Pune",
state: "Maharashtra",
pincode: "411001",
);
print(address.formatted); // Multi-line formatted address
print(address.city); // "Pune"
// Copy with modifications
final newAddress = address.copyWith(city: "Mumbai");
Use in Flutter Forms
All validators return String? making them perfect for TextFormField:
TextFormField(
decoration: InputDecoration(labelText: 'PAN Card'),
validator: IndianValidators.validatePAN,
autovalidateMode: AutovalidateMode.onUserInteraction,
)
Platform Support
This package supports all Dart platforms:
- ✅ Android
- ✅ iOS
- ✅ Web
- ✅ macOS
- ✅ Windows
- ✅ Linux
Dependencies
Zero external dependencies (except meta for annotations). Pure Dart implementation.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
Created by vivekTemp250602
Acknowledgments
- Indian numbering system standards
- TRAI mobile number series allocation
- GST state codes from GSTN
- Verhoeff algorithm for Aadhaar validation
Note: Mobile operator detection and PIN code to state mapping are approximate. For production use cases requiring exact data, consider integrating with official APIs.
Libraries
- formatters
- Formatters-only export for tree-shaking optimization.
- indian_formatters
- A comprehensive Flutter/Dart package for India-specific formatting, validation, and parsing.
- validators
- Validators-only export for tree-shaking optimization.
- validators/aadhaar
- Aadhaar validator only.
- validators/driving_license
- Driving License validator only.
- validators/gst
- GST validator only.
- validators/ifsc
- IFSC code validator only.
- validators/mobile
- Mobile number validator only.
- validators/pan
- PAN Card validator only.
- validators/pincode
- PIN code validator only.
- validators/upi
- UPI validator only.
- validators/voter_id
- Voter ID validator only.