37

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
Shubhamhackz
  • 7,333
  • 7
  • 50
  • 71

10 Answers10

60

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
Dlani Mendes
  • 771
  • 7
  • 5
  • Is it possible to do the same for string? i am having hard time doing this. – Mano Haran Jan 16 '21 at 23:10
  • 1
    @ManoHaran Hi! Use `double.tryParse("10000")` or `double.parse("10000")`, after this just format. – Dlani Mendes Jun 10 '21 at 18:06
  • Hi! I wonder how I can apply this to display the number with '.' as separator. When I tried code above, it returns me an error --> Multiple decimal separators in pattern "Instance of 'StringIterator'". How can we tell the package that we are going to use different separator. I've tried using locale, but it doesn't work. – Naufal Rajabi Aug 10 '22 at 15:05
  • Hi @NaufalRajabi choose a different locale based on your need and try this example: `var formatter = NumberFormat('#,##,000', "ar_DZ");` Reference => https://github.com/dart-lang/intl/blob/master/lib/number_symbols_data.dart – Dlani Mendes Sep 01 '22 at 22:51
21

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
Shubhamhackz
  • 7,333
  • 7
  • 50
  • 71
5

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
Feshibaba
  • 89
  • 1
  • 6
3

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
enadun
  • 3,107
  • 3
  • 31
  • 34
2

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();
  }
}
zex_rectooor
  • 692
  • 7
  • 26
1

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');
});
Gad D Lord
  • 6,620
  • 12
  • 60
  • 106
1

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);
  }
}
Ritesh Singh
  • 782
  • 9
  • 19
0

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. :)

0

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
Kishan Donga
  • 2,851
  • 2
  • 23
  • 35
0

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