Originaler README-Schnappschuss aus dem verknüpften Quell-Repository. Aktuelle Inhalte finden Sie im Repository.
Numeral
Composable number formatting and parsing for Dart.
Numeral turns application numbers into display strings and back again with
reusable codecs for decimals, compact values, percentages, byte sizes, currency
text, and locale-aware numerals. Create a codec once, keep it in your app
utilities, and use the same object for both formatting and parsing.
Installation
Add Numeral to your pubspec.yaml:
dependencies:
numeral: ^4.1.0
Usage
Import the codec entrypoint for built-in number display codecs:
import 'package:numeral/codec.dart';
import 'package:numeral/en.dart' as en;
package:numeral/numeral.dart contains the core protocols and shared models:
NumeralCodec, NumeralLanguage, NumeralUnitSet, NumeralUnit, and
Rounding.
Create reusable codec instances:
final fileSize = BytesCodec.binary(maxFractionDigits: 1);
final compact = en.compact(maxFractionDigits: 1);
final ratio = PercentCodec(maxFractionDigits: 2);
fileSize.format(1536);
fileSize.parse('1.5 KiB');
fileSize.encode(1536);
fileSize.decode('1.5 KiB');
compact.format(12345);
compact.parse('12.3K');
ratio.format(0.1234);
ratio.parse('12.34%');
For one-off formatting, import the extension entry:
import 'package:numeral/extension.dart';
import 'package:numeral/zh.dart' as zh;
12345.compact(maxFractionDigits: 1);
1536.bytes(binary: true, maxFractionDigits: 1);
1000000.currency('¥', style: zh.compact(maxFractionDigits: 0));
1000000.formatWith(zh.cardinal());
Codecs
Each codec extends Codec<T, String> from dart:convert.
format and parse are readable aliases for encode and decode, so both
styles work:
final bytes = BytesCodec.binary();
bytes.format(1024);
bytes.encode(1024);
bytes.parse('1 KiB');
bytes.decode('1 KiB');
Unit-style codecs such as compact numbers, percentages, byte sizes, and
currency can replace their internal number style with another codec. By
default, they use a DecimalCodec built from their decimal options.
Decimal
final amount = DecimalCodec(
minFractionDigits: 2,
maxFractionDigits: 2,
);
amount.format(1234567.8);
amount.parse('1,234,567.80');
Compact
import 'package:numeral/en.dart' as en;
final compact = en.compact(maxFractionDigits: 1);
compact.format(1234);
compact.format(999999);
compact.parse('3 million');
Custom unit sets use the same NumeralUnit model as byte codecs:
import 'package:numeral/codec.dart';
import 'package:numeral/numeral.dart';
final custom = CompactCodec(
unitSet: NumeralUnitSet([
NumeralUnit(1, ''),
NumeralUnit(1000, 'K', aliases: ['k']),
NumeralUnit(1000000, 'M', aliases: ['m']),
]),
);
custom.format(1234567);
custom.parse('3.5M');
Custom unit scales must be finite, positive, and strictly ascending. Parser
tokens are matched case-insensitively, so symbols and aliases should be unique
after lowercasing.
Percent
final percent = PercentCodec(maxFractionDigits: 1);
percent.format(0.1234);
percent.parse('12.3%');
Bytes
final decimalBytes = BytesCodec();
final binaryBytes = BytesCodec.binary(maxFractionDigits: 1);
decimalBytes.format(1500);
decimalBytes.parse('1.5 MB');
binaryBytes.format(1536);
binaryBytes.parse('1.5 KiB');
Currency
Currency formatting is display-oriented. Use a decimal or money type for
financial calculation, then use Numeral to render and parse strings.
import 'package:numeral/zh.dart' as zh;
final usd = CurrencyCodec(r'$');
final cny = CurrencyCodec(
'¥',
style: zh.compact(maxFractionDigits: 0),
);
usd.format(1234.5);
usd.parse(r'$1,234.50');
cny.format(1000000);
cny.parse('¥100万');
Parsing
Every codec has parse and tryParse:
final bytes = BytesCodec.binary();
bytes.parse('1 KiB');
bytes.tryParse('bad input');
parse returns the natural numeric type for the codec:
DecimalCodec.parse(...) returns num.
CompactCodec.parse(...) returns num.
PercentCodec.parse(...) returns double.
BytesCodec.parse(...) returns int.
CurrencyCodec.parse(...) returns num.
Language Paths
Built-in language packs live behind separate import paths. This keeps the core
API small while allowing locale-specific rules to include code, not only unit
data.
import 'package:numeral/zh.dart' as zh;
final compact = zh.compact(maxFractionDigits: 2);
final words = zh.cardinal();
final year = zh.year();
final financial = zh.financial();
final rmb = zh.rmb();
compact.format(1234567);
words.format(1000000);
words.format(2000000);
words.parse('一百万');
words.parse('两百万');
words.parse('一万零十');
words.parse('一万二');
year.format(2026);
financial.format(1000000);
rmb.format(1000000);
rmb.format(1234567.89);
Traditional Chinese is available from its own language path:
import 'package:numeral/zh_hant.dart' as zh_hant;
final compact = zh_hant.compact(maxFractionDigits: 2);
final words = zh_hant.cardinal();
final year = zh_hant.year();
final financial = zh_hant.financial();
compact.format(1234567);
compact.parse('2億');
words.format(1000000);
words.parse('兩百萬');
words.parse('一萬零十');
year.format(2026);
financial.format(1000000);
French is available from its own language path:
import 'package:numeral/fr.dart' as fr;
final compact = fr.compact(maxFractionDigits: 1);
final words = fr.cardinal();
final year = fr.year();
compact.format(1500000);
compact.parse('1,5 M');
words.format(2026);
words.parse('soixante-et-onze');
year.format(2026);
Korean is available from its own language path:
import 'package:numeral/ko.dart' as ko;
final compact = ko.compact(maxFractionDigits: 2);
final words = ko.cardinal();
final year = ko.year();
compact.format(12345);
compact.parse('2억');
words.format(1000000);
words.format(123456789);
words.parse('일억 이천만');
year.format(2026);
Japanese is available from its own language path:
import 'package:numeral/ja.dart' as ja;
final compact = ja.compact(maxFractionDigits: 2);
final words = ja.cardinal();
final year = ja.year();
compact.format(1234567);
compact.parse('2億');
words.format(1000000);
words.format(10000001);
words.parse('一万〇一');
words.parse('千五百万');
year.format(2026);
Spanish is available from its own language path:
import 'package:numeral/es.dart' as es;
final compact = es.compact(maxFractionDigits: 2);
final words = es.cardinal();
compact.format(1500000);
compact.parse('2 millones');
words.format(1000000);
words.format(1000000000);
words.format(1000000000000);
words.parse('veintiún mil');
External packages can build the same style of language path by reusing
NumeralLanguage, NumeralUnitSet, and NumeralCodec.
License
This library is licensed under the MIT License.