h4kuna / number-format
Object wrapper above number_format
Installs: 63 427
Dependents: 2
Suggesters: 0
Security: 0
Stars: 18
Watchers: 4
Forks: 4
Open Issues: 0
Requires
- php: >=8.0
- h4kuna/data-type: ^v3.0.5
Requires (Dev)
- ext-intl: *
- nette/tester: ^2.4
- nette/utils: ^3.0 || ^4.0
- phpstan/phpstan: ^1.8
- phpstan/phpstan-deprecation-rules: ^1.1.3
- phpstan/phpstan-strict-rules: ^1.4
- tracy/tracy: ^2.9
Suggests
- ext-intl: If you want to use IntlDateFormatter or NumberFormatter.
This package is auto-updated.
Last update: 2023-11-21 12:22:18 UTC
README
The library can format numbers like percent, currencies or number with unit, next are dates and convert between order of units.
composer require h4kuna/number-format
Changelog
Details is moved to file.
By statistic the version 3 is most used. I describe upgrade from v3.0 to v6.0.
- removed interface NumberFormat, now this is static class like wrap on number_format().
- all classes
NumberFormatState
,UnitFormatState
,UnitPersistentFormatState
are joined to one NumberFormatter - change namespace from
h4kuna\Number
toh4kuna\Format\Number
orh4kuna\Format\Number\Formatters
- removed support, defined parameters by array, from php8 is native by named parameters
NumberFormatter changes
- class
NumberFormatter
is immutable - is callable by
__invoke()
method - method format() has only one parameter,
$number
- mask has new char for unit, old
U
replaced by⎵
,NumberFormatter(mask: '⎵ 1')
- parameter
intOnly
was removed - parameter
round
is callback, see Round.php - add
nbsp
parameter - parameter
zeroClear
is integer instead of bool, see ZeroClear.php
Number
Formats
Keep formats in object and use if you need.
use h4kuna\Format\Number; $formats = new Number\Formats([ 'EUR' => static fn (Number\Formats $formats) => new Number\Formatters\NumberFormatter(decimals: 0, nbsp: false, unit: '€'), // callback like factory if is needed 'GBP' => new NumberFormatter(nbsp: false, unit: '£', mask: '⎵ 1'), ]); $formats->get('EUR')->format(5); // 5€ $formats->get('GBP')->format(5); // £ 5,00
NumberFormatter by h4kuna
The class provide many options, all options has default value. The class is immutable, the property are read only. If you want any to change of setup use method modify(). Both classes IntlNumberFormatter and NumberFormatter has implemented interface Formatter.
use h4kuna\Format\Number; // set decimals as 3 $numberFormat = new Number\Formatters\NumberFormatter(3); // or $numberFormat = new Number\Formatters\NumberFormatter(decimals: 3); echo $numberFormat->format(1000); // 1 000,000
Parameters
- decimals: [2]
- decimalPoint: [',']
- thousandsSeparator: [' ']
- nbsp: [true] replace space by like utf-8 char
- zeroClear:
- [ZeroClear::NO] disabled
- [ZeroClear::DECIMALS_EMPTY] 1.0 ->
1
, 1.50 ->1,50
- [ZeroClear::DECIMALS] 1.0 ->
1
; 1.50 ->1,5
- emptyValue: [\x00] disabled, if value is empty (by default
null
or empty string''
) will display some wildcard - zeroIsEmpty: [false] disabled, only
null
and empty string''
are replaced byemptyValue
, but by this option is zero empty value too - unit: [''] disabled, define unit for formatted number, $, €, kg etc...
- showUnitIfEmpty: [false] unit must be defined, show unit if is empty value
- mask: [1 ⎵] if you want to define 1 € or $ 1
- round: [null] change round function, let's use
Round::BY_CEIL
orRound::BY_FLOOR
Here are tests for more use cases.
Method modify()
use h4kuna\Format\Number; $numberFormat = new Number\Formatters\NumberFormatter(mask: '⎵ 1', decimals: 3, unit: '€'); echo $numberFormat->format(1000); // € 1 000,000 with nbsp $numberFormatDisableNbsp = $numberFormat->modify(nbsp: false); // keep previous setting and disable nbsp echo $numberFormatDisableNbsp->format(1000); // € 1 000,000
Native NumberFormatter
Create new class MyFormats and extends class Utils\Formats for right suggestion. And use native NumberFormatter.
use h4kuna\Format\Number;use h4kuna\Format\Utils; /** * @extends Utils\Formats<Number\Formatters\IntlNumberFormatter> */ class MyFormats extends Utils\Formats { } setlocale(LC_TIME, 'cs_CZ.utf8'); $formats = new MyFormats([ 'decimal' => static fn() => new Number\Formatters\IntlNumberFormatter(new \NumberFormatter(\Locale::getDefault(), \NumberFormatter::DECIMAL)), 'currency' => static fn() => new Number\Formatters\IntlNumberFormatter(new \NumberFormatter(\Locale::getDefault(), \NumberFormatter::CURRENCY)), ]); $formats->get('decimal')->format(1000.1235); // 1 000,124 $formats->get('currency')->format(1000.1235); // 1 000,12 Kč
Tax
use h4kuna\Format\Number; $tax = new Number\Tax(20); echo $tax->add(100); // 120 echo $tax->deduct(120); // 100.0 echo $tax->diff(120); // 20.0
Percent
use h4kuna\Format\Number; $percent = new Number\Percent(20); echo $percent->add(100); // 120.0 echo $percent->deduct(120); // 96.0 echo $percent->diff(120); // 24.0
Units\Unit
use h4kuna\Format\Number\Units; $unit = new Units\Unit(/* [string $from], [array $allowedUnits] */);
- $from select default prefix for your units default is BASE = 0
- $allowedUnits if we need other units if is defined
This example say: I have 50kilo (103) and convert to base 100
/** @var h4kuna\Format\Number\Units\Unit $unit */ $unitValue = $unit->convertFrom(50, $unit::KILO, $unit::BASE); echo $unitValue->unit; // empty string mean BASE echo $unitValue->value; // 50000
If second parameter is null
then use from unit whose is defined in constructor.
/** @var h4kuna\Format\Number\Units\Unit $unit */ $unitValue = $unit->convertFrom(5000, null, $unit::KILO); // alias for this use case is $unitValue = $unit->convert(5000, $unit::KILO); echo $unitValue->unit; // k mean KILO echo $unitValue->value; // 5
If third parameter is null
, class try to find the best unit.
/** @var h4kuna\Format\Number\Units\Unit $unit */ $unitValue = $unit->convertFrom(5000000, $unit::MILI, null); echo $unitValue->unit; // k mean KILO echo $unitValue->value; // 5
Last method, take string and convert how we need. This is good for Byte.
/** @var h4kuna\Format\Number\Units\Unit $unit */ $unitValue = $unit->fromString('100k', $unit::BASE); echo $unitValue->unit; // BASE echo $unitValue->value; // 100000
Units\Byte
use h4kuna\Format\Number\Units; $unitValue = $byte = new Units\Byte(); $byte->fromString('128M'); echo $unitValue->unit; // BASE echo $unitValue->value; // 134217728
Units\UnitFormat
If we need format our units.
use h4kuna\Format\Number; $nff = new Number\Formats(); $unitFormat = new Number\Units\UnitFormat('B', new Byte, $nff); $unitFormat->convert(968884224); // '924,00 MB' $unitFormat->convert(1024); // '1,00 kB'
Date
Define own formats for date and time. Both classes IntlDateFormatter and DateTimeFormatter has implemented interface Formatter.
use h4kuna\Format\Date; $formats = new Date\Formats([ 'date' => new Date\Formatters\DateTimeFormatter('j. n. Y'), 'time' => static fn () => new Date\Formatters\DateTimeFormatter('H:i'), // callback like factory if is needed 'dateTime' => static fn () => new Date\Formatters\DateTimeFormatter('j. n. Y H:i'), ]); $dateObject = new \DateTime('2023-06-13 12:30:40'); $formats->get('date')->format($dateObject); // 13. 6. 2023 $formats->get('time')->format($dateObject); // 12:30 $formats->get('dateTime')->format($dateObject); // 13. 6. 2023 12:30
For better use, you can extends class Formats and add your own methods.
use h4kuna\Format\Date; class MyFormats extends Date\Formats { public function date(?\DateTimeInterface $data): string { return $this->get('date')->format($data); } } $formats = new MyFormats([ 'date' => new Date\Formatters\DateTimeFormatter('j. n. Y'), ]); $dateObject = new \DateTime('2023-06-13 12:30:40'); $formats->date($dateObject); // 13. 6. 2023
Support IntlDateFormatter
Format by locale.
use h4kuna\Format\Date; use IntlDateFormatter; $intlFormatter = new IntlDateFormatter('cs_CZ', IntlDateFormatter::MEDIUM, IntlDateFormatter::MEDIUM,) $formats = new Date\Formats([ 'date' => new Date\Formatters\IntlDateFormatter($intlFormatter), ]); $date = new \DateTime('2023-06-13 12:30:40'); $formats->get('date')->format($date); // 12. 6. 2023 12:30:40
Integration to Nette framework
In your neon file, define service for keep formatting and register to latte
services: number: h4kuna\Format\Number\Formatters\NumberFormatter(decimalPoint: '.', decimals: 4) # support named parameters by nette percent: h4kuna\Format\Number\Formatters\NumberFormatter(decimalPoint: '.', decimals: 2, unit: '%') currency.czk: h4kuna\Format\Number\Formatters\NumberFormatter(decimalPoint: ',', decimals: 2, unit: 'Kč') currency.eur: h4kuna\Format\Number\Formatters\NumberFormatter(decimalPoint: '.', decimals: 2, unit: '€', mask: '⎵ 1') currencies: implement: h4kuna\Format\Number\FormatsAccessor( czk: @currency.czk eur: @currency.eur ) latte.latteFactory: setup: - addFilter('number', @number) - addFilter('percent', @percent) - addFilter('czk', @currency.czk) - addFilter('eur', @currency.eur)
We added new filters for formatting and service for currencies:
Formatting
use h4kuna\Format\Number\FormatsAccessor; class Invoice { public function __construct(private FormatsAccessor $formats) { } public function generate(): void { $number = 987.356; $currency = 'eur'; var_dump($this->formats->get($currency)->format($number)); } }
Latte template
{=10000|number} // this render "1 000.0000" with &nbps; like white space
Units
Help us convert units in general decimal system.