I have to format numbers as thousands separators in dart. I have numbers like:
16987
13876
456786
and I want to format them as :
16,987
13,876
4,56,786
You can use NumberFormat passing a custom format in ICU formatting pattern, take a look in NumberFormat.
import 'package:intl/intl.dart';
void main() {
var formatter = NumberFormat('#,##,000');
print(formatter.format(16987));
print(formatter.format(13876));
print(formatter.format(456786));
}
Output
16,987
13,876
4,56,786
I found NumberFormat class from intl package very useful as it provides different ways to format numbers.
By default the NumberFormat class format's number in million's using default American locale and we can format numbers in lakh using Indian locale(It can format number or currency according to any countries locale).NumberFormat.decimalPattern([String locale])
.
import 'package:intl/intl.dart';
void main() {
NumberFormat numberFormat = NumberFormat.decimalPattern('hi');
print(numberFormat.format(16987));
print(numberFormat.format(13876));
print(numberFormat.format(456786));
}
Output
16,987
13,876
4,56,786
You don`t need to use NumberFormat package before you can do that. this should help, test it with any number.
String formatAmount(){
String price = "1000000000";
String priceInText = "";
int counter = 0;
for(int i = (price.length - 1); i >= 0; i--){
counter++;
String str = price[i];
if((counter % 3) != 0 && i !=0){
priceInText = "$str$priceInText";
}else if(i == 0 ){
priceInText = "$str$priceInText";
}else{
priceInText = ",$str$priceInText";
}
}
return priceInText.trim();
}
Then you can use by printing:
print(formatAmount());
output:
1,000,000,000
If you want the comma separated value with decimals, use the decimalPatternDigits
initializer and control the number of decimal places via the decimalDigits
parameter.
Setting the decimalDigits
parameter value to 0
will result in no decimals.
With Decimals
import 'package:intl/intl.dart';
NumberFormat formatter = NumberFormat.decimalPatternDigits(
locale: 'en_us',
decimalDigits: 2,
);
print(formatter.format(17459));
print(formatter.format(1000000));
print(formatter.format(100100.05));
print(formatter.format(100100.016));
output
17,459.00
1,000,000.00
100,100.05
100,100.02
Without Decimals
import 'package:intl/intl.dart';
NumberFormat formatter = NumberFormat.decimalPatternDigits(
locale: 'en_us',
decimalDigits: 0,
);
print(formatter.format(100100.05));
print(formatter.format(100100.999));
output
100,100
100,101
Pseudocode for that activity would be around:
Here, `string` is an input string with indexes starting at 0.
let i = (length of string) - 3
while i > 0 do
insert a "," into string at position (i)
let i = i - 3
return string
DartCode
extension on int {
String get priceString {
final numberString = toString();
final numberDigits = List.from(numberString.split(''));
int index = numberDigits.length - 3;
while (index > 0) {
numberDigits.insert(index, ',');
index -= 3;
}
return numberDigits.join();
}
}
You can use this more flexible extension:
/// Return as number as formatted in thousands string.
/// Example: -123456.asThousands() returns -123'456
String asThousands({
final String separator = "'",
final int digits = 3,
}) {
assert(digits >= 1, '5d40ef0f-f8b4-4070-adf4-bbfc1a8b663b');
final chars =
abs().truncate().toString().split(StringHelper.empty).reversed;
var n = 0;
var result = StringHelper.empty;
for (final ch in chars) {
if (n == digits) {
result = '$ch$separator$result';
n = 1;
} else {
result = '$ch$result';
n++;
}
}
result = this < 0 ? '-$result' : result;
result = (this is double)
? '$result${toString().substring(toString().lastIndexOf('.'))}'
: result;
return result;
}
Sample calls:
test('Test NumHelper.asThousands()', () {
expect(
123456789.asThousands(separator: StringHelper.space),
'123 456 789',
);
expect(123456789.asThousands(separator: ','), '123,456,789');
expect(
123456789.asThousands(separator: ',', digits: 2),
'1,23,45,67,89',
);
expect((-123456789).asThousands(separator: ','), '-123,456,789');
expect((-123456).asThousands(separator: ','), '-123,456');
expect((-12345).asThousands(separator: ','), '-12,345');
expect(1.asThousands(), '1');
expect(12.asThousands(), '12');
expect(123.asThousands(), '123');
expect(1995.asThousands(), "1'995");
expect(12345678.asThousands(), "12'345'678");
expect((-123456789.123).asThousands(separator: ','), '-123,456,789.123');
});
Thats the Indian format for currency. Hence intl package lets you convert numbers to locale currency. Using the standard patterns. For Indian format you can use.
NumberFormat.currency(locale: 'en_IN', symbol: '₹ ').format(value);
Or you can create an extension like this.
import 'package:intl/intl.dart';
extension Currency on double {
String indianFormat() {
return NumberFormat.currency(locale: 'en_IN', symbol: '₹ ').format(this);
}
}
In case you want to format a number with the thousands separator and give it a max number of decimal numbers.
var formatter = NumberFormat('#,##0.' + "#" * 5);
print(formatter.format(double.parse('1000.456781234'.replaceAll(",", ""))));
OUTPUT: 1,000.45678
Hope this helps. :)
The easiest way here is a use NumberFormat class from the intl
, please follow the given steps for the same.
Add this package to your pubspec.yaml
dependencies:
intl: ^0.17.0
Use this below line of code in your dart extension file
final numberFormat = NumberFormat.decimalPattern('hi');
extension ExtOnNum on num {
format() {
final parts = toString().split('.');
return '${numberFormat.format(num.tryParse(parts[0]) ?? 0.0)}.${parts[1]}';
}
}
Output:
print(5843.41.format());
5,843.41
For thousand seperator
stringAmount.replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => "${m[1]}.");
'2352' ---> '2.352'
'3452' ---> '23.452'
'235223' ---> '235.223'
. is for Türkiye to use , seeperator change . to , from end of code