Skip to content

Commit

Permalink
Version 6.x
Browse files Browse the repository at this point in the history
  • Loading branch information
h4kuna committed Sep 1, 2023
1 parent f965521 commit cd2fe14
Show file tree
Hide file tree
Showing 42 changed files with 1,056 additions and 262 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
composer.lock
/vendor/
/**/output/
/coverage.html
257 changes: 201 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,62 +9,131 @@ Number Format
Wrapper above number_format, api is very easy.

# Changelog

## v6.0

- global namespace `h4kuna\Number` renamed to `h4kuna\Format`
- add new namespace `h4kuna\Format\Date`, other files move to namespace `h4kuna\Format\Number`
- behavior is same like v5.0 but namespaces are different
- add support for php native [NumberFormatter](https://www.php.net/manual/en/class.numberformatter.php)
- I don't keep back compatibility, because v5.0 is not widespread, but here are aliases. You can add to your project and
will work.

```php
use h4kuna;
class_alias(h4kuna\Format\Number\Formats::class, 'h4kuna\Number\Utils\Formats');
class_alias(h4kuna\Format\Number\NumberFormat::class, 'h4kuna\Number\Format');
class_alias(h4kuna\Format\Number\Percent::class, 'h4kuna\Number\Percent');
class_alias(h4kuna\Format\Number\Round::class, 'h4kuna\Number\Utils\Round');
class_alias(h4kuna\Format\Number\Tax::class, 'h4kuna\Number\Tax');
class_alias(h4kuna\Format\Number\UnitValue::class, 'h4kuna\Number\Utils\UnitValue');

// parameters
class_alias(h4kuna\Format\Number\Parameters\ZeroClear::class, 'h4kuna\Number\Parameters\Format\ZeroClear');

// formatters
class_alias(h4kuna\Format\Number\Formatters\NumberFormatter::class, 'h4kuna\Number\NumberFormat');

// namespace Unit
class_alias(h4kuna\Format\Number\Units\Byte::class, 'h4kuna\Number\Units\Byte');
class_alias(h4kuna\Format\Number\Units\Unit::class, 'h4kuna\Number\Units\Unit');
class_alias(h4kuna\Format\Number\Units\UnitFormat::class, 'h4kuna\Number\Units\UnitFormat');
```

## v5.0

- support php 8.0+
- add new static class [Format](src/Format.php), you can format numbers without instance of class
- add new static class [NumberFormat](src/Number/NumberFormat.php), you can format numbers without instance of class
- class NumberFormat is immutable
- **BC break** removed parameters like unit and decimals in method NumberFormat::format()
- let's use method modify()
- let's use method modify()
- class Parameters removed, because php 8.0 has native support
- **BC break** NumberFormat support for int numbers removed, like a parameter **intOnly**
- **BC break** NumberFormat removed method enableExtendFormat() all options move to constructor
- add new class Round
- class NumberFormatFactory removed
- parameter zeroClear is integer instead of bool

## v4.0
- removed dependency on h4kuna/data-type
- support php 7.4+
- removed interface NumberFormat
- renamed class NumberFormatState -> NumberFormat
- removed class UnitFormatState, replace by `NumberFormat` like `$nf = new NumberFormat(); $nf->enableExtendFormat();`
- removed class UnitPersistentFormatState, replace by `NumberFormat` like `$nf = new NumberFormat(); $nf->enableExtendFormat('1 MY_PERSISTENT_UNIT');`
- method format has second parameter like decimals and third is dynamic defined unit
- char for unit in mask changed to ``
- added parameter nbsp to NumberFormat::__construct()

Install via composer
-------------------

```sh
composer require h4kuna/number-format
```

## Number

### Formats

Keep formats in object and use if you need.

```php
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

```

### Native NumberFormatter

Create new class MyFormats and extends class [Utils\Formats](./src/Utils/Formats.php) for right suggestion.

```php
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č
```

### NumberFormat

Class has many parameters and all paremetes has default value. You can add parameters normaly by position or name of keys in array like first parameter.
Class has many parameters and all parameters has default value.

```php
use h4kuna\Number;
use h4kuna\Format\Number;

// set decimals as 3
$numberFormat = new Number\NumberFormat(3);
$numberFormat = new Number\Formatters\NumberFormatter(3);
// or
$numberFormat = new Number\NumberFormat(decimals: 3);
$numberFormat = new Number\Formatters\NumberFormatter(decimals: 3);

echo $numberFormat->format(1000); // 1 000,000
```

#### Parameters

- decimals: [2]
- decimalPoint: [',']
- thousandsSeparator: [' ']
- nbsp: [true] replace space by \&nbsp; 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`
- 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 by `emptyValue`, but by this option is zero empty value too
- zeroIsEmpty: [false] disabled, only `null` and empty string `''` are replaced by `emptyValue`, 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**
Expand All @@ -73,35 +142,36 @@ echo $numberFormat->format(1000); // 1 000,000
Here are tests for [more use cases](tests/src/NumberFormatTest.php).

### Format expect unit and use modify()

```php
use h4kuna\Number;
use h4kuna\Format\Number;

$numberFormat = new Number\NumberFormat(mask: '⎵ 1', decimals: 3, unit: '€');
$numberFormat = new Number\Formatters\NumberFormatter(mask: '⎵ 1', decimals: 3, unit: '€');
echo $numberFormat->format(1000, 3, '€'); // € 1 000,000 with nbsp

$numberFormatDisableNbsp = $numberFormat->modify(nbsp: false); // keep previous setting and disable nbsp
echo $numberFormatDisableNbsp->format(1000); // € 1 000,000
```

### Format persistent unit
This class is same like previous, but unit is persistent like currencies or temperature.

This class is same like previous, but unit is persistent like currencies or temperature.

```php
use h4kuna\Number;
use h4kuna\Format\Number;

$numberFormat = new Number\NumberFormat();
$numberFormat = new Number\Formatters\NumberFormatter();
$numberFormat->enableExtendFormat('€ 1');

echo $numberFormat->format(1000); // € 1 000,00
```

### NumberFormatFactory
For all previous cases is prepared [factory class](src/NumberFormatFactory.php). This class help you create new instance and support named parameters in constructor. [Visit test](tests/src/NumberFormatFactoryTest.php)

### Tax

```php
$tax = new Tax(20);
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
Expand All @@ -110,49 +180,35 @@ echo $tax->diff(120); // 20.0
### Percent

```php
$percent = new Percent(20);
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
```

## Integration to Nette framework

In your neon file
```neon
services:
number: h4kuna\Number\NumberFormat(decimalPoint: '.', intOnly: 1, decimals: 1) #support named parameters by nette
latte.latteFactory:
setup:
- addFilter('number', [@number, 'format'])
```

We added new filter number, in template use like:
```html
{=10000|number} // this render "1 000.0" with &nbps; like white space
```

# Units
Help us convert units in general [decimal system](//en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes).

### Units\Unit

```php
use h4kuna\Number\Units;
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 (10<sup>3</sup>) and convert to base 10<sup>0</sup>

```php
$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.

```php
$unitValue = $unit->convertFrom(5000, NULL, $unit::KILO);
// alias for this use case is
Expand All @@ -161,34 +217,123 @@ $unitValue = $unit->convert(5000, $unit::KILO);
echo $unitValue->unit; // k mean KILO
echo $unitValue->value; // 5
```
If third parameter is NULL, class try find best unit.

If third parameter is NULL, class try to find the best unit.

```php
$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.

```php
$unitValue = $unit->fromString('100k', $unit::BASE);
echo $unitValue->unit; // BASE
echo $unitValue->value; // 100000
```

### Units\Byte

```php
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.

```php
$nff = new Number\NumberFormatFactory();
$unitfFormat = new Units\UnitFormat('B', new Byte, $nff->createUnit());
use h4kuna\Format\Number\Units;
$nff = new Number\Formats();
$unitfFormat = new Units\UnitFormat('B', new Byte, $nff);

$unitfFormat->convert(968884224); // '924,00 MB'
$unitfFormat->convert(1024); // '1,00 kB'
```

## Date

Define own formats for date and time.

```php
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.

```php
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.

```php
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

```neon
services:
number: h4kuna\Format\Number\NumberFormat(decimalPoint: '.', intOnly: 1, decimals: 1) #support named parameters by nette
latte.latteFactory:
setup:
- addFilter('number', [@number, 'format'])
```

We added new filter number, in template use like:

```html
{=10000|number} // this render "1 000.0" with &nbps; like white space
```

# Units

Help us convert units in general [decimal system](//en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes).
Loading

0 comments on commit cd2fe14

Please sign in to comment.