PHP Classes

File: _docs/NumberFormatter.md

Recommend this page to a friend!
  Packages of Caleb   PHP Common Class Library   _docs/NumberFormatter.md   Download  
File: _docs/NumberFormatter.md
Role: Example script
Content type: text/markdown
Description: Example script
Class: PHP Common Class Library
Set of classes that provides common functionality
Author: By
Last change: Number formatter update.

Changelog excerpt:
- Added Aegean, Osmanya, Hmong, Adlam, N'Ko, and Malayalam support to the
number formatter.
Date: 7 months ago
Size: 31,034 bytes
 

Contents

Class file image Download

Documentation for the "NumberFormatter" class.

Used by CIDRAM and phpMussel to format numbers generated by their front-end pages, the class provides a more controllable, customisable mechanism for number formatting than PHP's internal number_format() function.

How to use:

NumberFormatter constructor.

public function __construct(string $Format = '');

To use the number formatter, you'll firstly need to instantiate it. You don't need to parse any parameters to the constructor, but it optionally accepts one parameter, $Format. The $Format parameter can be used to immediately set various commonly used values to the object's properties during object instantiation (so that you won't need to set each definition manually). You can set these later though. More information about these properties will be explained later in this document. The currently supported values for $Format are listed in the table below.

Value | ConversionSet | GroupSeparator | GroupSize | GroupOffset | DecimalSeparator | Base ---|---|---|---|---|---|--- Default values (e.g., when the parameter is omitted) and Latin-1. | Western | ,<br />(comma) | 3 | 0 | .<br />(decimal) | 10 Adlam | Adlam | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 Aegean [?1] [?3] [?4] | Aegean | (empty) | (n/a) | (n/a) | (empty) | 10 Arabic-1 | Eastern | (empty) | (n/a) | (n/a) | ?<br />(arabic decimal separator) | 10 Arabic-2 | Eastern | ?<br />(arabic thousands separator) | 3 | 0 | ?<br />(arabic decimal separator) | 10 Arabic-3 or Persian | Persian | ?<br />(arabic thousands separator) | 3 | 0 | ?<br />(arabic decimal separator) | 10 Arabic-4 or Urdu | Persian | ?<br />(arabic thousands separator) | 2 | -1 | ?<br />(arabic decimal separator) | 10 Armenian [?3] [?4] | Armenian | (empty) | (n/a) | (n/a) | (empty) | 10 Base-12 [?2] | Western | (empty) | (n/a) | (n/a) | .<br />(decimal) | 12 Base-16 [?2] | Western | (empty) | (n/a) | (n/a) | .<br />(decimal) | 16 Bengali-1 or Nagari | Nagari | ,<br />(comma) | 2 | -1 | .<br />(decimal) | 10 Burmese-1 | Burmese | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 China-1 | Western | ,<br />(comma) | 4 | 0 | .<br />(decimal) | 10 Chinese-Simplified-Financial [?4] | ChineseSimplifiedFinancial | (empty) | (n/a) | (n/a) | ?<br />(U+70B9) | 10 Chinese-Simplified [?4] | ChineseSimplified | (empty) | (n/a) | (n/a) | ?<br />(U+70B9) | 10 Chinese-Traditional-Financial [?4] | ChineseTraditionalFinancial | (empty) | (n/a) | (n/a) | ?<br />(U+9EDE) | 10 Chinese-Traditional [?4] | ChineseTraditional | (empty) | (n/a) | (n/a) | ?<br />(U+9EDE) | 10 Etruscan [?3] [?4] | Etruscan | (empty) | (n/a) | (n/a) | (empty) | 10 Fullwidth | Fullwidth | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 Geez [?3] | Geez | (empty) | (n/a) | (n/a) | (empty) | 10 Hebrew [?3] [?4] | Hebrew | (empty) | (n/a) | (n/a) | (empty) | 10 Hmong | Hmong | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 India-1 | Western | ,<br />(comma) | 2 | -1 | .<br />(decimal) | 10 India-2 or Devanagari | Devanagari | ,<br />(comma) | 2 | -1 | .<br />(decimal) | 10 India-3 or Gujarati | Gujarati | ,<br />(comma) | 2 | -1 | .<br />(decimal) | 10 India-4 or Gurmukhi or Punjabi | Gurmukhi | ,<br />(comma) | 2 | -1 | .<br />(decimal) | 10 India-5 or Kannada | Kannada | ,<br />(comma) | 2 | -1 | .<br />(decimal) | 10 India-6 or Telugu | Telugu | ,<br />(comma) | 2 | -1 | .<br />(decimal) | 10 Japanese [?4] | Japanese | (empty) | (n/a) | (n/a) | ?<br />(katakana middle dot) | 10 Javanese | Javanese | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 Kaktovik | Kaktovik | (empty) | (n/a) | (n/a) | .<br />(decimal) | 20 Khmer-1 | Khmer | .<br />(decimal) | 3 | 0 | ,<br />(comma) | 10 Lao-1 | Lao | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 Latin-2 | Western | ?<br />(non-breaking space) | 3 | 0 | .<br />(decimal) | 10 Latin-3 | Western | .<br />(decimal) | 3 | 0 | ,<br />(comma) | 10 Latin-4 | Western | ?<br />(non-breaking space) | 3 | 0 | ,<br />(comma) | 10 Latin-5 | Western | ,<br />(comma) | 3 | 0 | ·<br />(middle dot) | 10 Mayan [?1] [?2] | Mayan | (empty) | (n/a) | (n/a) | .<br />(decimal) | 20 Malayalam | Malayalam | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 MalayalamOld [?3] [?4] | MalayalamOld | (empty) | (n/a) | (n/a) | (empty) | 10 Mongolian | Mongolian | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 NKo | NKo | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 NoSep-1 | Western | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 NoSep-2 | Western | (empty) | (n/a) | (n/a) | ,<br />(comma) | 10 Odia | Odia | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 Osmanya | Osmanya | `<br />(space) |3|0|.<br />(decimal) |10` Roman [?3] [?4] | Roman | (empty) | (n/a) | (n/a) | (empty) | 10 SDN-Dwiggins | Dwiggins | ,<br />(comma) | 3 | 0 | ;<br />(semicolon) | 12 SDN-Pitman | Pitman | ,<br />(comma) | 3 | 0 | ;<br />(semicolon) | 12 Tamil [?3] [?4] | Tamil | (empty) | (n/a) | (n/a) | (empty) | 10 Thai-1 | Thai | ,<br />(comma) | 3 | 0 | .<br />(decimal) | 10 Thai-2 | Thai | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10 Tibetan | Tibetan | (empty) | (n/a) | (n/a) | .<br />(decimal) | 10

[?1]: Not actually "commonly used" at all, seeing as it hasn't been actively used for several centuries now (or in some cases, for several millenia now), so unlikely to be practical, but serves as a nice easter egg for the class.

[?2]: The class fully supports fractions, including the ability to convert between arbitrary bases for both decimals and fractions alike, and including for numeral systems, that the class supports, that mightn't necessarily themselves support fractions natively, or in the contexts where those numeral systems would normally be used. It's not my intention to imply that they should. However, the support already exists, removing it for specific numeral systems would require additional code complexity, and doing so would be generally pointless, I think. Alternatively, any users concerned about this can easily just omit the $Decimals parameter when calling format() to avoid fractions.

[?3]: Fractions not supported in this context, either because fractions don't make sense in the context of the conversion set used, or because supporting fractions in this context would significantly increase code complexity.

[?4]: The conversion set used has a range limit (i.e., numbers outside the range limit can't be rendered or represented accurately).

(n/a): Means "not applicable".

format method.

After instantiating the number formatter, after setting any necessary values for the instance's properties, the format method is used to format numbers.

public function format($Number, int $Decimals = 0): string;

The method accepts two parameters.

The first parameter, $Number, is the number you want to format (mandatory). The method uses this parameter in a way consistent with strings, but any scalar value (e.g., string, int, float) can be used.

The second parameter, $Decimals, is an optional integer (defaults to 0), and tells the method how many decimal places you expect the formatted number to have.

Example:

<?php
$Formats = [
    'Adlam',
    'Aegean',
    'Arabic-1',
    'Arabic-2',
    'Arabic-3',
    'Arabic-4',
    'Armenian',
    'Base-12',
    'Base-16',
    'Bengali-1',
    'Burmese-1',
    'China-1',
    'Chinese-Simplified',
    'Chinese-Simplified-Financial',
    'Chinese-Traditional',
    'Chinese-Traditional-Financial',
    'Etruscan',
    'Fullwidth',
    'Geez',
    'Hebrew',
    'Hmong',
    'India-1',
    'India-2',
    'India-3',
    'India-4',
    'India-5',
    'India-6',
    'Japanese',
    'Javanese',
    'Kaktovik',
    'Khmer-1',
    'Lao-1',
    'Latin-1',
    'Latin-2',
    'Latin-3',
    'Latin-4',
    'Latin-5',
    'Mayan',
    'Malayalam',
    'MalayalamOld',
    'Mongolian',
    'NKo',
    'NoSep-1',
    'NoSep-2',
    'Odia',
    'Roman',
    'SDN-Dwiggins',
    'SDN-Pitman',
    'Tamil',
    'Thai-1',
    'Thai-2',
    'Tibetan'
];

echo "Format | `\$Obj->format('1234567.89', 2)` | `\$Obj->format('10203040.50607080', 5)` | `\$Obj->format('100.75', 3)` | `\$Obj->format('99999999', 0)`\n:--|--:|--:|--:|--:\n";

foreach ($Formats as $Format) {
    $Obj = new \Maikuolan\Common\NumberFormatter($Format);
    echo '`' . $Format . '` | `' . $Obj->format('1234567.89', 2) . '` | `' . $Obj->format('10203040.50607080', 5) . '` | `' . $Obj->format('100.75', 3) . '` | `' . $Obj->format('99999999', 0) . "`\n";
}

Output:

Format | $Obj->format('1234567.89', 2) | $Obj->format('10203040.50607080', 5) | $Obj->format('100.75', 3) | $Obj->format('99999999', 0) :--|--:|--:|--:|--: Adlam | ???????.?? | ????????.????? | ???.??? | ???????? Aegean | ` ||?|` Arabic-1 | ?????????? | ?????????????? | ??????? | ???????? Arabic-2 | ???????????? | ???????????????? | ??????? | ?????????? Arabic-3 | ???????????? | ???????????????? | ??????? | ?????????? Arabic-4 | ???????????? | ????????????????? | ??????? | ??????????? Armenian | ?????????? | ?????? | ? | ???????????? Base-12 | 4b6547.a8 | 3500654.60a5a | 84.900 | 295a6453 Base-16 | 12d687.e3 | 9bafa0.818dd | 64.c00 | 5f5e0ff Bengali-1 | ??,??,???.?? | ?,??,??,???.????? | ???.??? | ?,??,??,??? Burmese-1 | ???????.?? | ????????.????? | ???.??? | ???????? China-1 | 123,4567.89 | 1020,3040.50607 | 100.750 | 9999,9999 Chinese-Simplified | ???????????????? | ??????????????? | ?????? | ??????????????? Chinese-Simplified-Financial | ???????????????? | ??????????????? | ?????? | ??????????????? Chinese-Traditional | ???????????????? | ??????????????? | ?????? | ??????????????? Chinese-Traditional-Financial | ???????????????? | ??????????????? | ?????? | ??????????????? Etruscan | ` ||?|` Fullwidth | ???????.?? | ????????.????? | ???.??? | ???????? Geez | ????????? | ??????? | ? | ??????????? Hebrew | ?????????????? | ?????????? | ? | ?????????????????? Hmong | ???????.?? | ????????.????? | ???.??? | ???????? India-1 | 12,34,567.89 | 1,02,03,040.50607 | 100.750 | 9,99,99,999 India-2 | ??,??,???.?? | ?,??,??,???.????? | ???.??? | ?,??,??,??? India-3 | ??,??,???.?? | ?,??,??,???.????? | ???.??? | ?,??,??,??? India-4 | ??,??,???.?? | ?,??,??,???.????? | ???.??? | ?,??,??,??? India-5 | ??,??,???.?? | ?,??,??,???.????? | ???.??? | ?,??,??,??? India-6 | ??,??,???.?? | ?,??,??,???.????? | ???.??? | ?,??,??,??? Japanese | ?????????????????? | ??????????????? | ????? | ?????????????????? Javanese | ???????.?? | ????????.????? | ???.??? | ???????? Kaktovik | ?????.?? | ??????.????? | ??.??? | ??????? Khmer-1 | ?.???.???,?? | ??.???.???,????? | ???,??? | ??.???.??? Lao-1 | ???????.?? | ????????.????? | ???.??? | ???????? Latin-1 | 1,234,567.89 | 10,203,040.50607 | 100.750 | 99,999,999 Latin-2 | 1?234?567.89 | 10?203?040.50607 | 100.750 | 99?999?999 Latin-3 | 1.234.567,89 | 10.203.040,50607 | 100,750 | 99.999.999 Latin-4 | 1?234?567,89 | 10?203?040,50607 | 100,750 | 99?999?999 Latin-5 | 1,234,567·89 | 10,203,040·50607 | 100·750 | 99,999,999 Mayan | ?????.?? | ??????.????? | ??.??? | ??????? Malayalam | ???????.?? | ????????.????? | ???.??? | ???????? MalayalamOld | ??????????????? | ?????????? | ? | ???????????????????? Mongolian | ???????.?? | ????????.????? | ???.??? | ???????? NKo | ???????.?? | ????????.????? | ???.??? | ???????? NoSep-1 | 1234567.89 | 10203040.50607 | 100.750 | 99999999 NoSep-2 | 1234567,89 | 10203040,50607 | 100,750 | 99999999 Odia | ???????.?? | ????????.????? | ???.??? | ???????? Osmanya | ? ??? ???.?? | ?? ??? ???.????? | ???.??? | ?? ??? ??? Roman | M?C?C?X?X?X?I?V?DLXVII | ` |C|` SDN-Dwiggins | 4E6,547;X8 | 3,500,654;60X5X | 84;900 | 29,5X6,453 SDN-Pitman | 4?6,547;?8 | 3,500,654;60?5? | 84;900 | 29,5?6,453 Tamil | ??????????????? | ?????????? | ? | ???????????????????? Thai-1 | ?,???,???.?? | ??,???,???.????? | ???.??? | ??,???,??? Thai-2 | ???????.?? | ????????.????? | ???.??? | ???????? Tibetan | ???????.?? | ????????.????? | ???.??? | ????????

getSetJSON method.

Gets the specified conversion set and returns it as a JSON string. Not normally needed by the implementation, but can sometimes be useful if the implementation needs further work done on numbers outside the scope of the number formatter itself.

$Obj = new \Maikuolan\Common\NumberFormatter();
echo $Obj->getSetJSON('Javanese') . PHP_EOL;
echo $Obj->getSetJSON('Roman') . PHP_EOL;
echo $Obj->getSetJSON('Persian') . PHP_EOL;

Output:

["\ua9d0","\ua9d1","\ua9d2","\ua9d3","\ua9d4","\ua9d5","\ua9d6","\ua9d7","\ua9d8","\ua9d9"]
{".":true,"0":"","1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":"","9":"","^0+1":"I","^0+2":"II","^0+3":"III","^0+4":"IV","^0+5":"V","^0+6":"VI","^0+7":"VII","^0+8":"VIII","^0+9":"IX","^1+1":"X","^1+2":"XX","^1+3":"XXX","^1+4":"XL","^1+5":"L","^1+6":"LX","^1+7":"LXX","^1+8":"LXXX","^1+9":"XC","^2+1":"C","^2+2":"CC","^2+3":"CCC","^2+4":"CD","^2+5":"D","^2+6":"DC","^2+7":"DCC","^2+8":"DCCC","^2+9":"CM","^3+1":"M","^3+2":"MM","^3+3":"MMM","^3+4":"I\u0305V\u0305","^3+5":"V\u0305","^3+6":"V\u0305I\u0305","^3+7":"V\u0305I\u0305I\u0305","^3+8":"V\u0305I\u0305I\u0305I\u0305","^3+9":"I\u0305X\u0305","^4+1":"X\u0305","^4+2":"X\u0305X\u0305","^4+3":"X\u0305X\u0305X\u0305","^4+4":"X\u0305L\u0305","^4+5":"L\u0305","^4+6":"L\u0305X\u0305","^4+7":"L\u0305X\u0305X\u0305","^4+8":"L\u0305X\u0305X\u0305X\u0305","^4+9":"X\u0305C\u0305","^5+1":"C\u0305","^5+2":"C\u0305C\u0305","^5+3":"C\u0305C\u0305C\u0305","^5+4":"C\u0305D\u0305","^5+5":"D\u0305","^5+6":"D\u0305C\u0305","^5+7":"D\u0305C\u0305C\u0305","^5+8":"D\u0305C\u0305C\u0305C\u0305","^5+9":"C\u0305M\u0305","^6+1":"M\u0305","^6+2":"M\u0305M\u0305","^6+3":"M\u0305M\u0305M\u0305"}
["\u06f0","\u06f1","\u06f2","\u06f3","\u06f4","\u06f5","\u06f6","\u06f7","\u06f8","\u06f9"]

unformat method.

Unformats the formatted number according to predefined patterns and lookup tables.

public function unformat(string $Number, string $DecSep = '', int $MinBase = 10): string;

The first parameter is the number to be unformatted, the second parameter is the decimal separator to look for (when specified, the method will attempt to unformat fractions, and when not specified, won't, except under certain specific circumstances), and the third parameter is the minimum number base to interpret from the source number. Unformatted number returned as a string rather than as an integer or a float in order to retain decimal precision.

Warning: Doesn't work for ALL formats (..yet).

$Obj = new \Maikuolan\Common\NumberFormatter('Arabic-2');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;

$Obj = new \Maikuolan\Common\NumberFormatter('India-2');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;

$Obj = new \Maikuolan\Common\NumberFormatter('Geez');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;

$Obj = new \Maikuolan\Common\NumberFormatter('Kaktovik');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;

Output:

??????????????????????
12345678987654321
??,??,??,??,??,??,??,???
12345678987654321
????????????????????????
12345678987654321
?????????????
12345678987654321

A note regarding number vaguity.

In some cases, the exact numeric value represented by a provided number may, from the perspective of the number formatter, be vague.

Take "X", for example. "X" can represent "10" in Roman numerals and in duodecimal notation, and can represent "33" when using a number base greater than 33. So, if the unformat method encounters an "X", how does it know whether to interpret that as 10 or 33? It uses a little guesswork based on common sense. If the instance's "Base" property is set to 12 (meaning that numbers should be formatted using base-12), it's reasonable to assume the context of the instance would be expecting a duodecimal, and therefore, reasonable to interpret that X as 10. If the instance's "Base" property is set to 10 (meaning that numbers should be formatted using base-10), and the provided number doesn't contain any characters other than those used in Roman numerals (i.e., it may contain Vs, Xs, Ls, Cs, etc, but doesn't contain any 1s, 2s, 3s, 4s, etc), it's reasonable to assume the context of the instance would be expecting a Roman numeral, and therefore, reasonable to interpret that X as 10. In other cases (i.e., the instance hasn't been explicitly set to base-12 and the provided number contains non-Roman numeral characters), it's more reasonable to interpret that X as 33.

Take "E", as another example. "E" can represent "11" in duodecimal notation, and can represent "14" when using a number base greater than 14. Just as with the previous example, if the instance's "Base" property is set to 12, it's reasonable to assume the context of the instance would be expecting a duodecimal, and therefore, reasonable to interpret that E as 11, and in other cases, it's more reasonable to interpret that E as 14.

Will those interpretations always be correct? No. But it should be correct most of the time.

limits method.

Guards for the upper and lower limits of the current conversion set.

public function limits($Number): bool;

Used internally by the format method and for tests (unlikely to be needed by the implementation). Returns true when the given number is outside the upper or lower limits.

ConversionSet property.

public $ConversionSet = 'Western';

The ConversionSet property tells the number formatter which characters it should to use to represent which numbers.

Currently supported values:

Value | Description ---|--- Western | Standard numerals (0-9), alternatively known as Western Arabic numerals, Arabic numerals, Hindu-Arabic numerals, etc. Adlam | Adlam numerals. Aegean | Aegean numerals. (Fractions not supported. Range limit: 1 ~ 99,999). Armenian | Armenian numerals. (Fractions not supported. Range limit: 1 ~ 99,999,999). Burmese | Burmese numerals. ChineseSimplifiedFinancial | Financial simplified Chinese numerals. (Range upper limit: 10<sup>^48</sup>-1). ChineseSimplified | Standard simplified Chinese numerals. (Range upper limit: 10<sup>^48</sup>-1). ChineseTraditionaFinancial | Financial traditional Chinese numerals. (Range upper limit: 10<sup>^48</sup>-1). ChineseTraditional | Standard traditional Chinese numerals. (Range upper limit: 10<sup>^48</sup>-1). Devanagari | Devanagari numerals. Eastern | Eastern Arabic numerals. Etruscan | Etruscan numerals. (Fractions not supported. Range limit: 1 ~ 499). Fullwidth | Fullwidth numerals. Geez | Ge'ez/Ethiopic numerals. (Fractions not supported. Range lower limit: 1). Gujarati | Gujarati numerals. Gurmukhi | Gurmukhi numerals. Hebrew | Hebrew numerals. (Fractions not supported. Range limit: 1 ~ 10<sup>^16</sup>-1). Hmong | Hmong numerals. Japanese | Japanese numerals. (Range limit: 10<sup>^-11</sup>+1 ~ 10<sup>^24</sup>-1). Javanese | Javanese numerals. Kaktovik | Kaktovik numerals. Kannada | Kannada numerals. Khmer | Khmer numerals. Lao | Lao numerals. Mayan | Mayan numerals. Malayalam | Malayalam numerals (modern/reformed). MalayalamOld | Malayalam numerals (old/pre-reformation). Mongolian | Mongolian numerals. NKo | N'Ko numerals. Nagari | Nagari/Bengali/Bangla numerals. Odia | Odia numerals. OlChiki | Ol Chiki numerals. Osmanya | Osmanya numerals. Persian | Persian/Urdu numerals (Eastern Arabic variant). Roman | Roman numerals. (Fractions not supported. Range limit: 1 ~ 3,999,999). Tamil | Tamil numerals. (Fractions not supported. Range limit: 1 ~ 10<sup>^24</sup>-1). Telugu | Telugu numerals. Thai | Thai numerals. Tibetan | Tibetan numerals.

(If needed, the class can easily be extended to add support for additional conversion sets).

Example usage:

$Obj = new \Maikuolan\Common\NumberFormatter();

$Obj->ConversionSet = 'Devanagari';
echo $Obj->format('123.45', 2) . PHP_EOL;

$Obj->ConversionSet = 'Kannada';
echo $Obj->format('123.45', 2) . PHP_EOL;

$Obj->ConversionSet = 'Western';
echo $Obj->format('123.45', 2) . PHP_EOL;

Output:

???.??
???.??
123.45

GroupSeparator property.

public $GroupSeparator = ',';

The GroupSeparator property tells the number formatter which character to use to separate groups of numbers (e.g., the comma in 1,234.56).

Example usage:

$Obj = new \Maikuolan\Common\NumberFormatter();

$Obj->GroupSeparator = "'";
echo $Obj->format('1234567.89', 2) . PHP_EOL;

$Obj->GroupSeparator = ',';
echo $Obj->format('1234567.89', 2) . PHP_EOL;

$Obj->GroupSeparator = '.';
$Obj->DecimalSeparator = ',';
echo $Obj->format('1234567.89', 2) . PHP_EOL;

Output:

1'234'567.89
1,234,567.89
1.234.567,89

GroupSize property.

public $GroupSize = 3;

The GroupSize property tells the number formatter how many numbers should from a number group (typically this is three, but sometimes other sizes may be needed).

Example usage:

$Obj = new \Maikuolan\Common\NumberFormatter();

$Obj->GroupSize = 4;
echo $Obj->format('1234567.89', 2) . PHP_EOL;

$Obj->GroupSize = 3;
echo $Obj->format('1234567.89', 2) . PHP_EOL;

$Obj->GroupSize = 2;
echo $Obj->format('1234567.89', 2) . PHP_EOL;

Output:

123,4567.89
1,234,567.89
1,23,45,67.89

GroupOffset property.

public $GroupOffset = 0;

The GroupOffset property provides a mechanism by which the first number group in a number can be a different size to any subsequent number groups in the number. This can be particularly important when expressing numbers that deal with lakhs and crores, typically requiring that the first number group contain three numbers, with any subsequent number groups containing two numbers.

Example usage:

$Obj = new \Maikuolan\Common\NumberFormatter();

$Obj->GroupOffset = -2;
echo $Obj->format('1000000000000000') . PHP_EOL;

$Obj->GroupOffset = -1;
echo $Obj->format('1000000000000000') . PHP_EOL;

$Obj->GroupOffset = 0;
echo $Obj->format('1000000000000000') . PHP_EOL;

$Obj->GroupOffset = 1;
echo $Obj->format('1000000000000000') . PHP_EOL;

$Obj->GroupOffset = 2;
echo $Obj->format('1000000000000000') . PHP_EOL;

$Obj->GroupSize = 2;
$Obj->GroupOffset = -1;
echo $Obj->format('1000000000000000') . PHP_EOL;

Output:

10,000,000,000,00000
100,000,000,000,0000
1,000,000,000,000,000
10,000,000,000,000,00
100,000,000,000,000,0
1,00,00,00,00,00,00,000

DecimalSeparator property.

public $DecimalSeparator = '.';

The DecimalSeparator property tells the number formatter which character to use to separate whole numbers from fractions (e.g., the period in 1,234.56).

Example usage:

$Obj = new \Maikuolan\Common\NumberFormatter();

$Obj->DecimalSeparator = "?";
echo $Obj->format('1234567.89', 2) . PHP_EOL;

$Obj->DecimalSeparator = "?";
echo $Obj->format('1234567.89', 2) . PHP_EOL;

$Obj->GroupSeparator = '.';
$Obj->DecimalSeparator = ',';
echo $Obj->format('1234567.89', 2) . PHP_EOL;

Output:

1,234,567?89
1,234,567?89
1.234.567,89

Base property.

public $Base = 10;

The Base property tells the number formatter which base to use to express numbers. This will typically be 10, but sometimes other bases may be needed. The mechanism for switching between bases relies upon PHP's internal base_convert() function, which requires that bases be between 2 and 36 inclusive. The Base property must therefore be set to a value between 2 and 36 inclusive (otherwise it won't work properly).

An example that uses 1e+9 (1,000,000,000):

$Obj = new \Maikuolan\Common\NumberFormatter();

for ($Obj->Base = 2; $Obj->Base < 37; $Obj->Base++) {
    echo 'Base ' . $Obj->Base . ': ' . $Obj->format(1e+9) . PHP_EOL;
}

Output:

Base 2: 111,011,100,110,101,100,101,000,000,000
Base 3: 2,120,200,200,021,010,001
Base 4: 323,212,230,220,000
Base 5: 4,022,000,000,000
Base 6: 243,121,245,344
Base 7: 33,531,600,616
Base 8: 7,346,545,000
Base 9: 2,520,607,101
Base 10: 1,000,000,000
Base 11: 473,523,88a
Base 12: 23a,a93,854
Base 13: 12c,23a,19c
Base 14: 96,b4b,6b6
Base 15: 5c,bd1,46a
Base 16: 3b,9ac,a00
Base 17: 27,750,aa7
Base 18: 1b,73h,dda
Base 19: 12,4g6,g1i
Base 20: f,ca0,000
Base 21: b,dhi,eed
Base 22: 8,i0i,7fa
Base 23: 6,h8a,c3k
Base 24: 5,5e1,n2g
Base 25: 4,2a0,000
Base 26: 3,647,joc
Base 27: 2,fii,731
Base 28: 2,22p,q5k
Base 29: 1,jlp,2ii
Base 30: 1,b4h,13a
Base 31: 1,3sp,5mg
Base 32: tpl,ig0
Base 33: pi7,fla
Base 34: m0a,nuo
Base 35: j1d,lik
Base 36: gjd,gxs

Now, as an example to demonstrate working with fractions:

$Obj = new \Maikuolan\Common\NumberFormatter();

for ($Obj->Base = 2; $Obj->Base < 37; $Obj->Base++) {
    echo 'Base ' . $Obj->Base . ': ' . $Obj->format('10.5', 4) . ' ~ ' . $Obj->format('256.25', 4) . PHP_EOL;
}

Output:

Base 2: 1,010.1000 ~ 100,000,000.0100
Base 3: 101.1111 ~ 100,111.0202
Base 4: 22.2000 ~ 10,000.1000
Base 5: 20.2222 ~ 2,011.1111
Base 6: 14.3000 ~ 1,104.1300
Base 7: 13.3333 ~ 514.1515
Base 8: 12.4000 ~ 400.2000
Base 9: 11.4444 ~ 314.2222
Base 10: 10.5000 ~ 256.2500
Base 11: a.5555 ~ 213.2828
Base 12: a.6000 ~ 194.3000
Base 13: a.6666 ~ 169.3333
Base 14: a.7000 ~ 144.3700
Base 15: a.7777 ~ 121.3b3b
Base 16: a.8000 ~ 100.4000
Base 17: a.8888 ~ f1.4444
Base 18: a.9000 ~ e4.4900
Base 19: a.9999 ~ d9.4e4e
Base 20: a.a000 ~ cg.5000
Base 21: a.aaaa ~ c4.5555
Base 22: a.b000 ~ be.5b00
Base 23: a.bbbb ~ b3.5h5h
Base 24: a.c000 ~ ag.6000
Base 25: a.cccc ~ a6.6666
Base 26: a.d000 ~ 9m.6d00
Base 27: a.dddd ~ 9d.6k6k
Base 28: a.e000 ~ 94.7000
Base 29: a.eeee ~ 8o.7777
Base 30: a.f000 ~ 8g.7f00
Base 31: a.ffff ~ 88.7n7n
Base 32: a.g000 ~ 80.8000
Base 33: a.gggg ~ 7p.8888
Base 34: a.h000 ~ 7i.8h00
Base 35: a.hhhh ~ 7b.8q8q
Base 36: a.i000 ~ 74.9000

Important: Please be aware that switching bases may result in a loss of precision (meaning that the resulting formatted numbers may sometimes be subject to some degree of inaccuracy).

Last Updated: 13 July 2025 (2025.07.13).