Commit 2a15ae12 by Carsten Brandt

refactored number formatting

parent a4e86c02
...@@ -13,7 +13,6 @@ use IntlDateFormatter; ...@@ -13,7 +13,6 @@ use IntlDateFormatter;
use NumberFormatter; use NumberFormatter;
use yii\helpers\HtmlPurifier; use yii\helpers\HtmlPurifier;
use yii\helpers\Html; use yii\helpers\Html;
use yii\i18n\FormatDefs;
/** /**
* Formatter provides a set of commonly used data formatting methods. * Formatter provides a set of commonly used data formatting methods.
...@@ -25,25 +24,10 @@ use yii\i18n\FormatDefs; ...@@ -25,25 +24,10 @@ use yii\i18n\FormatDefs;
* Formatter is configured as an application component in [[\yii\base\Application]] by default. * Formatter is configured as an application component in [[\yii\base\Application]] by default.
* You can access that instance via `Yii::$app->formatter`. * You can access that instance via `Yii::$app->formatter`.
* *
* The Formatter class is designed to format values according to a [[locale]]. For this feature to work
* TODO docs * the [PHP intl extension](http://php.net/manual/en/book.intl.php) has to be installed.
* This refactored formatter version combines localized i18n with base functions. If "intl" extension is installed * Most of the methods however work also if the PHP intl extension is not installed by providing
* ICU standard is used internally. If "intl" want to be used or can't be loaded most functionality is simulated with php. * a fallback implementation. Without intl month and day names are in english only.
* A separate definiton class in 'yii\i18n\FormatDefs.php' has an array with localized format defintions.
* As a constraint month and day names are in english only.
*
* The communication with formatter class is per standard with php format patterns. They are converted internally to
* icu format patterns. Further it supports for date, time and datetime the named patterns "short", "medium", "long" and
* "full" plus "db" (database), also if "intl" isn't loaded. The format function has an option parameter to use "icu"
* format patterns.
*
* All number fomatters of yii\i18n\ are merged with yii\base in this formatter. Formatted numbers aren't readable for
* a machine as numeric. Therefore an "unformat" function for all "format" types has been built.
*
* For currency amounts the currency code is taken from "intl" (if loaded). Otherwise it can be defined in a localizing
* array (formatterIntl). The rounding rule can be defined in config with "$roundingIncrement". For Swiss Francs formatter rounds
* automatically to 5 cents.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @author Enrica Ruedin <e.ruedin@guggach.com> * @author Enrica Ruedin <e.ruedin@guggach.com>
...@@ -62,11 +46,13 @@ class Formatter extends Component ...@@ -62,11 +46,13 @@ class Formatter extends Component
* @var array the text to be displayed when formatting a boolean value. The first element corresponds * @var array the text to be displayed when formatting a boolean value. The first element corresponds
* to the text displayed for `false`, the second element for `true`. * to the text displayed for `false`, the second element for `true`.
* Defaults to `['No', 'Yes']`, where `Yes` and `No` * Defaults to `['No', 'Yes']`, where `Yes` and `No`
* will be translated according to [[locale]].. * will be translated according to [[locale]].
*/ */
public $booleanFormat; public $booleanFormat;
/** /**
* @var string the locale ID that is used to localize the date and number formatting. * @var string the locale ID that is used to localize the date and number formatting.
* For number and date formatting this is only effective when the
* [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed.
* If not set, [[\yii\base\Application::language]] will be used. * If not set, [[\yii\base\Application::language]] will be used.
*/ */
public $locale; public $locale;
...@@ -79,27 +65,25 @@ class Formatter extends Component ...@@ -79,27 +65,25 @@ class Formatter extends Component
*/ */
public $timeZone; public $timeZone;
/** /**
* @var string the default format string to be used to format a date. * @var string the default format string to be used to format a [[asDate()|date]].
* This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths.
* *
* It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime).
*
* Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the
* PHP [date()](http://php.net/manual/de/function.date.php)-function. * PHP [date()](http://php.net/manual/de/function.date.php)-function.
*/ */
public $dateFormat = 'medium'; public $dateFormat = 'medium';
/** /**
* @var string the default format string to be used to format a time. * @var string the default format string to be used to format a [[asTime()|time]].
* This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths.
* *
* It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime).
*
* Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the
* PHP [date()](http://php.net/manual/de/function.date.php)-function. * PHP [date()](http://php.net/manual/de/function.date.php)-function.
*/ */
public $timeFormat = 'medium'; public $timeFormat = 'medium';
/** /**
* @var string the default format string to be used to format a date and time. * @var string the default format string to be used to format a [[asDateTime()|date and time]].
* This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths.
* *
* It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime).
...@@ -108,48 +92,48 @@ class Formatter extends Component ...@@ -108,48 +92,48 @@ class Formatter extends Component
* PHP [date()](http://php.net/manual/de/function.date.php)-function. * PHP [date()](http://php.net/manual/de/function.date.php)-function.
*/ */
public $datetimeFormat = 'medium'; public $datetimeFormat = 'medium';
// TODO refactor number formatters
/**
* @var array the options to be set for the NumberFormatter objects (eg. grouping used). Please refer to
* [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute)
* for the possible options. This property is used by [[createNumberFormatter]] when
* creating a new number formatter to format decimals, currencies, etc.
*/
public $numberFormatOptions = [];
/**
* @var array the text options to be set for the NumberFormatter objects (eg. Negative sign). Please refer to
* [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute)
* for the possible options. This property is used by [[createNumberFormatter]] when
* creating a new number formatter to format decimals, currencies, etc.
*
* Default value: GOUPING_USED = 1 / MAX_FRACTION_DIGITS = 3 / GROUPING_SIZE = 3 / ROUNDING_MODE = 4
*/
public $numberTextFormartOptions = [];
/** /**
* @var string the character displayed as the decimal point when formatting a number. * @var string the character displayed as the decimal point when formatting a number.
* If not set, the decimal separator corresponding to [[locale]] will be used. * If not set, the decimal separator corresponding to [[locale]] will be used.
* If PHP `intl` extension is not available, the default value is '.'. * If [PHP intl extension](http://php.net/manual/en/book.intl.php) is not available, the default value is '.'.
*/ */
public $decimalSeparator; public $decimalSeparator;
/** /**
* @var string the character displayed as the thousands separator character when formatting a number. * @var string the character displayed as the thousands separator (also called grouping separator) character when formatting a number.
* If not set, the thousand separator corresponding to [[locale]] will be used. * If not set, the thousand separator corresponding to [[locale]] will be used.
* If PHP `intl` extension is not available, the default value is ','. * If [PHP intl extension](http://php.net/manual/en/book.intl.php) is not available, the default value is ','.
*/ */
public $thousandSeparator; public $thousandSeparator;
// TODO refactor number formatters
// /**
// * @var array the options to be set for the NumberFormatter objects (eg. grouping used). Please refer to
// * [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute)
// * for the possible options. This property is used by [[createNumberFormatter]] when
// * creating a new number formatter to format decimals, currencies, etc.
// */
// public $numberFormatOptions = [];
// /**
// * @var array the text options to be set for the NumberFormatter objects (eg. Negative sign). Please refer to
// * [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute)
// * for the possible options. This property is used by [[createNumberFormatter]] when
// * creating a new number formatter to format decimals, currencies, etc.
// *
// * Default value: GOUPING_USED = 1 / MAX_FRACTION_DIGITS = 3 / GROUPING_SIZE = 3 / ROUNDING_MODE = 4
// */
// public $numberTextFormartOptions = [];
/** /**
* @var string the international currency code displayed when formatting a number. * @var string the international currency code displayed when formatting a number.
* If not set, the currency code corresponding to [[locale]] will be used. * If not set, the currency code corresponding to [[locale]] will be used. TODO default value?
*/ */
public $currencyCode; public $currencyCode;
/** // /**
* @var float "intl" numberformat library knows a rounding increment // * @var float "intl" numberformat library knows a rounding increment
* This means that any value is rounded to this increment. // * This means that any value is rounded to this increment.
* Example: increment of 0.05 rounds values <= 2.024 to 2.00 / values >= 2.025 to 2.05 // * Example: increment of 0.05 rounds values <= 2.024 to 2.00 / values >= 2.025 to 2.05
*/ // */
public $roundingIncrement; // public $roundingIncrement;
public $roundingIncrCurrency; // public $roundingIncrCurrency;
/** /**
* @var array the format used to format size (bytes). Three elements may be specified: "base", "decimals" and "decimalSeparator". * @var array the format used to format size (bytes). Three elements may be specified: "base", "decimals" and "decimalSeparator".
* They correspond to the base at which a kilobyte is calculated (1000 or 1024 bytes per kilobyte, defaults to 1024), * They correspond to the base at which a kilobyte is calculated (1000 or 1024 bytes per kilobyte, defaults to 1024),
...@@ -162,7 +146,7 @@ class Formatter extends Component ...@@ -162,7 +146,7 @@ class Formatter extends Component
]; ];
/** /**
* @var boolean whether the php `intl` extension is loaded. * @var boolean whether the [PHP intl extension](http://php.net/manual/en/book.intl.php) is loaded.
*/ */
private $_intlLoaded = false; private $_intlLoaded = false;
...@@ -185,8 +169,11 @@ class Formatter extends Component ...@@ -185,8 +169,11 @@ class Formatter extends Component
$this->nullDisplay = '<span class="not-set">' . Yii::t('yii', '(not set)') . '</span>'; $this->nullDisplay = '<span class="not-set">' . Yii::t('yii', '(not set)') . '</span>';
} }
$this->_intlLoaded = extension_loaded('intl'); $this->_intlLoaded = extension_loaded('intl');
if (!$this->_intlLoaded) {
$this->decimalSeparator = '.';
$this->thousandSeparator = ',';
}
// TODO refactor number formatters
// if (extension_loaded('intl')) { // if (extension_loaded('intl')) {
// $this->_intlLoaded = true; // $this->_intlLoaded = true;
// $this->numberFormatOptions = [NumberFormatter::ROUNDING_MODE => NumberFormatter::ROUND_HALFUP]; // $this->numberFormatOptions = [NumberFormatter::ROUNDING_MODE => NumberFormatter::ROUND_HALFUP];
...@@ -537,8 +524,9 @@ class Formatter extends Component ...@@ -537,8 +524,9 @@ class Formatter extends Component
// replace short, medium, long and full with real patterns in case intl is not loaded. // replace short, medium, long and full with real patterns in case intl is not loaded.
if (isset($this->_phpNameToPattern[$format][$type])) { if (isset($this->_phpNameToPattern[$format][$type])) {
$format = $this->_phpNameToPattern[$format][$type]; $format = $this->_phpNameToPattern[$format][$type];
} else {
$format = $this->getPhpDatePattern($format);
} }
$format = $this->getPhpDatePattern($format);
$date = new DateTime(null, new \DateTimeZone($this->timeZone)); $date = new DateTime(null, new \DateTimeZone($this->timeZone));
$date->setTimestamp($value); $date->setTimestamp($value);
return $date->format($format); return $date->format($format);
...@@ -572,6 +560,7 @@ class Formatter extends Component ...@@ -572,6 +560,7 @@ class Formatter extends Component
// if ( !($date === false)) break; // if ( !($date === false)) break;
// } // }
// TODO throw InvalidParamException on invalid value
} catch (\Exception $e) { } catch (\Exception $e) {
return null; return null;
} }
...@@ -788,6 +777,7 @@ class Formatter extends Component ...@@ -788,6 +777,7 @@ class Formatter extends Component
* *
* @param integer|string|DateTime|\DateInterval $referenceTime if specified the value is used instead of now * @param integer|string|DateTime|\DateInterval $referenceTime if specified the value is used instead of now
* @return string the formatted result * @return string the formatted result
* @throws InvalidParamException if the input value can not be evaluated as a date value.
*/ */
public function asRelativeTime($value, $referenceTime = null) public function asRelativeTime($value, $referenceTime = null)
{ {
...@@ -869,67 +859,30 @@ class Formatter extends Component ...@@ -869,67 +859,30 @@ class Formatter extends Component
// number formats // number formats
// TODO refactor number formatters
/** /**
* Formats the value as an integer and rounds decimals with math rule * Formats the value as an integer number by removing any digits without rounding.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted
* @return string the formatting result. * @return string the formatting result.
* @throws InvalidParamException if the input value is not numeric.
*/ */
public function asInteger($value, $grouping = true) { public function asInteger($value) // TODO customizing
$format = null; {
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
} }
if (is_string($value)) { $value = $this->normalizeNumericValue($value);
$value = (float) $value; if ($this->_intlLoaded) {
} $f = $this->createNumberFormatter(NumberFormatter::DECIMAL);
$value = round($value, 0);
if ($this->_intlLoaded){
$f = $this->createNumberFormatter(NumberFormatter::DECIMAL, $format);
if ($grouping === false){
$f->setAttribute(NumberFormatter::GROUPING_USED, false);
}
return $f->format($value, NumberFormatter::TYPE_INT64); return $f->format($value, NumberFormatter::TYPE_INT64);
} else { } else {
$grouping = $grouping === true ? $this->thousandSeparator : ''; return number_format((int) $value, 0, $this->decimalSeparator, $this->thousandSeparator);
return number_format($value, 0, $this->decimalSeparator, $grouping);
} }
} }
/** /**
* Formats the value as a number with decimal and thousand separators. * Formats the value as a decimal number.
* This method is a synomym for asDouble. *
* @param mixed $value the value to be formatted
* @param integer $decimals the number of digits after the decimal point
* @return string the formatted result
* @see decimalSeparator
* @see thousandSeparator
*/
public function asNumber($value, $decimals = 0, $roundIncr = null, $grouping = true)
{
return $this->asDouble($value, $decimals, $roundIncr, $grouping);
}
/**
* Formats the value as a decimal number. This method is a synonym for asDouble
* @see method asDouble
* @param mixed $value the value to be formatted
* @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details)
* for details on how to specify a format.
* @return string the formatted result.
*/
public function asDecimal($value, $decimals = null, $roundIncr = null, $grouping = true)
{
return $this->asDouble($value, $decimals, $roundIncr, $grouping);
}
/**
* Formats the value as a double number.
* Property [[decimalSeparator]] will be used to represent the decimal point. The * Property [[decimalSeparator]] will be used to represent the decimal point. The
* value is rounded automatically to the defined decimal digits. * value is rounded automatically to the defined decimal digits.
* *
...@@ -938,84 +891,70 @@ class Formatter extends Component ...@@ -938,84 +891,70 @@ class Formatter extends Component
* (eg. 2.5 [6]). Until 5 fractional digits in this function is defined to 5 up with zeros. * (eg. 2.5 [6]). Until 5 fractional digits in this function is defined to 5 up with zeros.
* *
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted
* @param integer or string $decimals the number of digits after the decimal point if the value is an integer * @param integer|string $decimals the number of digits after the decimal point if the value is an integer
* otherwise it's is a format pattern string (this works only with intl [icu]). * otherwise it's is a format pattern string (this works only with [PHP intl extension](http://php.net/manual/en/book.intl.php) [icu]).
* @param float $roundIncr Amount to which smaller fractation are rounded. Ex. 0.05 -> <=2.024 to 2.00 / >=2.025 to 2.05 // * @param float $roundIncr Amount to which smaller fractation are rounded. Ex. 0.05 -> <=2.024 to 2.00 / >=2.025 to 2.05
* works with "intl" library only. // * works with [PHP intl extension](http://php.net/manual/en/book.intl.php) library only.
* @param boolean $grouping Per standard numbers are grouped in thousands. False = no grouping // * @param boolean $grouping Per standard numbers are grouped in thousands. False = no grouping
* @return string the formatting result. * @return string the formatting result.
* @throws InvalidParamException if the input value is not numeric.
* @see decimalSeparator * @see decimalSeparator
* @see thousandSeparator * @see thousandSeparator
*/ */
public function asDouble($value, $decimals = 2, $roundIncr = null, $grouping = true) public function asDecimal($value, $decimals = 2)
{ {
$format = null;
if(is_numeric($decimals)){
$decimals = intval($decimals); // number of digits after decimal
} else {
$format = $decimals; // format pattern for ICU only
}
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
} }
if (is_string($value)){ $value = $this->normalizeNumericValue($value);
if (is_numeric($value)){
$value = (float)$value;
} else {
throw new InvalidParamException('"' . $value . '" is not a numeric value.');
}
}
// if (true === false){ if ($this->_intlLoaded) {
if ($this->_intlLoaded){ $f = $this->createNumberFormatter(NumberFormatter::DECIMAL);
$f = $this->createNumberFormatter(NumberFormatter::DECIMAL, $format); // if ($decimals !== null){
if ($decimals !== null){ // $f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
$f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals); // if ($decimals <= 5){
if ($decimals <= 5){ // $f->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals);
$f->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals); // }
} // }
} // if ($roundIncr == null and $this->roundingIncrement != null){
if ($roundIncr == null and $this->roundingIncrement != null){ // $roundIncr = $this->roundingIncrement;
$roundIncr = $this->roundingIncrement; // }
} // if ($roundIncr != null){
if ($roundIncr != null){ // $f->setAttribute(NumberFormatter::ROUNDING_INCREMENT, $roundIncr);
$f->setAttribute(NumberFormatter::ROUNDING_INCREMENT, $roundIncr); // }
} // if ($grouping === false){
if ($grouping === false){ // $f->setAttribute(NumberFormatter::GROUPING_USED, false);
$f->setAttribute(NumberFormatter::GROUPING_USED, false); // }
}
return $f->format($value); return $f->format($value);
} else { } else {
if ($roundIncr !== null){ // if ($roundIncr !== null){
$part = explode('.', (string)$roundIncr); // $part = explode('.', (string)$roundIncr);
if ((string)$roundIncr != '0.05'){ // exception for Swiss rounding. // if ((string)$roundIncr != '0.05'){ // exception for Swiss rounding.
$roundIncr = $decimals; // $roundIncr = $decimals;
if (intval($part[0]) > 0){ // if (intval($part[0]) > 0){
if (substr($part[0], 0, 1) === '1'){ // if (substr($part[0], 0, 1) === '1'){
$roundIncr = (strlen($part[0]) -1) * -1 ; // $roundIncr = (strlen($part[0]) -1) * -1 ;
} else { // } else {
throw new InvalidParamException('$roundIncr must have "1" only eg. 0.01 or 10 but not 0.02 or 20'); // throw new InvalidParamException('$roundIncr must have "1" only eg. 0.01 or 10 but not 0.02 or 20');
} // }
} elseif (isset($part[1]) and intval($part[1])>0) { // } elseif (isset($part[1]) and intval($part[1])>0) {
if (substr($part[1], -1) === '1'){ // if (substr($part[1], -1) === '1'){
$roundIncr = strlen($part[1]); // $roundIncr = strlen($part[1]);
} else { // } else {
throw new InvalidParamException('$roundIncr must have "1" only eg. 0.01 or 10 but not 0.02 or 20'); // throw new InvalidParamException('$roundIncr must have "1" only eg. 0.01 or 10 but not 0.02 or 20');
} // }
} // }
$value = round($value, $roundIncr); // $value = round($value, $roundIncr);
} else { // } else {
$value = round($value/5,2)*5; // $value = round($value/5,2)*5;
} // }
} // }
if ($decimals === null){ // if ($decimals === null){
$decimals = 0; // $decimals = 0;
} // }
$grouping = $grouping === true ? $this->thousandSeparator : ''; // $grouping = $grouping === true ? $this->thousandSeparator : '';
return number_format($value, $decimals, $this->decimalSeparator, $grouping); return number_format($value, $decimals, $this->decimalSeparator, $this->thousandSeparator);
} }
} }
...@@ -1023,88 +962,68 @@ class Formatter extends Component ...@@ -1023,88 +962,68 @@ class Formatter extends Component
/** /**
* Formats the value as a percent number with "%" sign. * Formats the value as a percent number with "%" sign.
* @param mixed $value the value to be formatted. It must be a factor eg. 0.75 -> 75% * @param mixed $value the value to be formatted. It must be a factor eg. 0.75 -> 75%
* @param string $format Number of decimals (default = 2) or format pattern ICU // * @param string $format Number of decimals (default = 2) or format pattern ICU
* Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) // * Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details)
* for details on how to specify a format. // * for details on how to specify a format.
* @param int $decimals
// * @param bool $grouping
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric.
*/ */
public function asPercent($value, $format = null, $decimals = 0, $grouping = true) public function asPercent($value, $decimals = 0)
{ {
if(is_numeric($decimals)){
$decimals = intval($decimals); // number of digits after decimal
} else {
$format = $decimals; // format pattern for ICU only
}
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
} }
if (is_string($value)) { $value = $this->normalizeNumericValue($value);
$value = (float) $value;
}
// if (true === false){ if ($this->_intlLoaded) {
if ($this->_intlLoaded){ $f = $this->createNumberFormatter(NumberFormatter::PERCENT);
$f = $this->createNumberFormatter(NumberFormatter::PERCENT, $format); // if ($decimals !== null){
if ($decimals !== null){ // $f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
$f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals); // if ($decimals <= 5){
if ($decimals <= 5){ // $f->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals);
$f->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals); // }
} // }
} // if ($grouping === false){
if ($grouping === false){ // $f->setAttribute(NumberFormatter::GROUPING_USED, false);
$f->setAttribute(NumberFormatter::GROUPING_USED, false); // }
}
return $f->format($value); return $f->format($value);
} else { } else {
if ($decimals === null){
$decimals = 0;
}
$value = $value * 100; $value = $value * 100;
$grouping = $grouping === true ? $this->thousandSeparator : ''; return number_format($value, $decimals, $this->decimalSeparator, $this->thousandSeparator) . '%';
return number_format($value, $decimals, $this->decimalSeparator, $grouping) . '%';
} }
} }
/** /**
* Formats the value as a scientific number. * Formats the value as a scientific number.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted
* @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) // * @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details)
* for details on how to specify a format. // * for details on how to specify a format.
* @param int $decimals
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric.
*/ */
public function asScientific($value, $decimals = null) public function asScientific($value, $decimals = 0)
{ {
$format = null;
if(is_numeric($decimals)){
$decimals = intval($decimals); // number of digits after decimal
} else {
$format = $decimals; // format pattern for ICU only
}
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
} }
if (is_string($value)) { $value = $this->normalizeNumericValue($value);
$value = (float) $value;
}
// if (true === false){
if ($this->_intlLoaded){ if ($this->_intlLoaded){
$f = $this->createNumberFormatter(NumberFormatter::SCIENTIFIC, $format); $f = $this->createNumberFormatter(NumberFormatter::SCIENTIFIC);
if ($decimals !== null){ // if ($decimals !== null){
$f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals); // $f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
} // }
return $f->format($value); return $f->format($value);
} else { } else {
if ($decimals !== null){ if ($decimals !== null) {
return sprintf("%.{$decimals}E", $value); return sprintf("%.{$decimals}E", $value);
} else { } else {
return sprintf("%.E", $value); return sprintf("%.E", $value);
} }
} }
} }
/** /**
...@@ -1112,50 +1031,84 @@ class Formatter extends Component ...@@ -1112,50 +1031,84 @@ class Formatter extends Component
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted
* @param string $currency the 3-letter ISO 4217 currency code indicating the currency to use. * @param string $currency the 3-letter ISO 4217 currency code indicating the currency to use.
* @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) * @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details)
* for details on how to specify a format. TODO ignored when not intl * for details on how to specify a format. TODO ignored when not [PHP intl extension](http://php.net/manual/en/book.intl.php)
* @param float $roundIncrement : Amount to which smaller fractation are rounded. Ex. 0.05 -> <=2.024 to 2.00 / >=2.025 to 2.05 * @param float $roundIncrement : Amount to which smaller fractation are rounded. Ex. 0.05 -> <=2.024 to 2.00 / >=2.025 to 2.05
* works with "intl" library only. * works with "intl" library only.
* @param null $grouping * @param null $grouping
* @throws InvalidParamException
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric.
*/ */
public function asCurrency($value, $currency = null, $format = null, $roundIncrement = null, $grouping = null) public function asCurrency($value, $currency = null) //, $format = null, $roundIncrement = null, $grouping = null)
{ {
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
} }
$value = $this->normalizeNumericValue($value); // TODO maybe not a good idea to cast money values?
if (is_string($value)) {
if (is_numeric($value)) {
$value = (float)$value;
} else {
throw new InvalidParamException('"' . $value . '" is not a numeric value.');
}
}
if ($currency === null) { if ($currency === null) {
$currency = $this->currencyCode; $currency = $this->currencyCode;
} }
if ($roundIncrement === null and $this->roundingIncrCurrency != null){ // if ($roundIncrement === null and $this->roundingIncrCurrency != null){
$roundIncrement = $this->roundingIncrCurrency; // $roundIncrement = $this->roundingIncrCurrency;
} // }
// if (true == false){
if ($this->_intlLoaded) { if ($this->_intlLoaded) {
$formatter = $this->createNumberFormatter(NumberFormatter::CURRENCY, $format); $formatter = $this->createNumberFormatter(NumberFormatter::CURRENCY);
if ($grouping !== null){ // if ($grouping !== null){
$formatter->setAttribute(NumberFormatter::GROUPING_USED, false); // $formatter->setAttribute(NumberFormatter::GROUPING_USED, false);
} // }
if ($roundIncrement !== null){ // if ($roundIncrement !== null){
$formatter->setAttribute(NumberFormatter::ROUNDING_INCREMENT, $roundIncrement); // $formatter->setAttribute(NumberFormatter::ROUNDING_INCREMENT, $roundIncrement);
} // }
return $formatter->formatCurrency($value, $currency); return $formatter->formatCurrency($value, $currency);
} else { } else {
return $currency . ' ' . $this->asDouble($value, 2, $roundIncrement, $grouping); return $currency . ' ' . $this->asDecimal($value, 2);
} }
} }
/**
* Formats the value as a number spellout.
* // TODO requires intl
* @param mixed $value the value to be formatted
* @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric.
* @throws NotSupportedException
*/
public function asSpellout($value)
{
if ($value === null) {
return $this->nullDisplay;
}
$value = $this->normalizeNumericValue($value);
if ($this->_intlLoaded){
$f = $this->createNumberFormatter(NumberFormatter::SPELLOUT);
return $f->format($value);
} else {
throw new NotSupportedException('Format as Spellout is only supported when PHP intl extension is installed.');
}
}
/**
* Formats the value as a ordinal value of a number.
* // TODO requires intl
* @param mixed $value the value to be formatted
* @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric.
* @throws NotSupportedException
*/
public function asOrdinal($value)
{
if ($value === null) {
return $this->nullDisplay;
}
$value = $this->normalizeNumericValue($value);
if ($this->_intlLoaded){
$f = $this->createNumberFormatter(NumberFormatter::ORDINAL);
return $f->format($value);
} else {
throw new NotSupportedException('Format as Ordinal is only supported when PHP intl extension is installed.');
}
}
/** /**
* Formats the value in bytes as a size in human readable form. * Formats the value in bytes as a size in human readable form.
...@@ -1163,22 +1116,21 @@ class Formatter extends Component ...@@ -1163,22 +1116,21 @@ class Formatter extends Component
* @param boolean $verbose if full names should be used (e.g. bytes, kilobytes, ...). * @param boolean $verbose if full names should be used (e.g. bytes, kilobytes, ...).
* Defaults to false meaning that short names will be used (e.g. B, KB, ...). * Defaults to false meaning that short names will be used (e.g. B, KB, ...).
* @return string the formatted result * @return string the formatted result
* @throws InvalidParamException if the input value is not numeric.
* @see sizeFormat * @see sizeFormat
*/ */
public function asSize($value, $verbose = false) public function asSize($value, $verbose = false)
{ {
$position = 0; $position = 0;
do { do {
if ($value < $this->sizeFormat['base']) { if ($value < $this->sizeFormat['base']) {
break; break;
} }
$value = $value / $this->sizeFormat['base']; $value = $value / $this->sizeFormat['base'];
$position++; $position++;
} while ($position < 6); } while ($position < 6);
$value = round($value, $this->sizeFormat['decimals']); $value = round($value, $this->sizeFormat['decimals']); // todo
$formattedValue = isset($this->sizeFormat['decimalSeparator']) ? str_replace('.', $this->sizeFormat['decimalSeparator'], $value) : $value; $formattedValue = isset($this->sizeFormat['decimalSeparator']) ? str_replace('.', $this->sizeFormat['decimalSeparator'], $value) : $value;
$params = ['n' => $formattedValue]; $params = ['n' => $formattedValue];
...@@ -1198,6 +1150,17 @@ class Formatter extends Component ...@@ -1198,6 +1150,17 @@ class Formatter extends Component
} }
} }
protected function normalizeNumericValue($value)
{
if (is_string($value) && is_numeric($value)) {
$value = (float) $value;
}
if (!is_numeric($value)) {
throw new InvalidParamException("'$value' is not a numeric value.");
}
return $value;
}
/** /**
* Creates a number formatter based on the given type and format. * Creates a number formatter based on the given type and format.
...@@ -1208,26 +1171,34 @@ class Formatter extends Component ...@@ -1208,26 +1171,34 @@ class Formatter extends Component
* [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) * [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details)
* @return NumberFormatter the created formatter instance * @return NumberFormatter the created formatter instance
*/ */
protected function createNumberFormatter($type, $format) protected function createNumberFormatter($style)
{ {
$formatter = new NumberFormatter($this->locale, $type); $formatter = new NumberFormatter($this->locale, $style);
if ($format !== null) {
$formatter->setPattern($format); if ($this->decimalSeparator !== null) {
} else {
$formatter->setSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL, $this->decimalSeparator); $formatter->setSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL, $this->decimalSeparator);
}
if ($this->thousandSeparator !== null) {
$formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator); $formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator);
} }
if (!empty($this->numberFormatOptions)) { // if ($format !== null) {
foreach ($this->numberFormatOptions as $name => $attribute) { // $formatter->setPattern($format);
$formatter->setAttribute($name, $attribute); // } else {
} // $formatter->setSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL, $this->decimalSeparator);
} // $formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator);
if (!empty($this->numberTextFormatOptions)) { // }
foreach ($this->numberTextFormatOptions as $name => $attribute) {
$formatter->setTextAttribute($name, $attribute); // if (!empty($this->numberFormatOptions)) {
} // foreach ($this->numberFormatOptions as $name => $attribute) {
} // $formatter->setAttribute($name, $attribute);
// }
// }
// if (!empty($this->numberTextFormatOptions)) {
// foreach ($this->numberTextFormatOptions as $name => $attribute) {
// $formatter->setTextAttribute($name, $attribute);
// }
// }
return $formatter; return $formatter;
} }
......
...@@ -71,7 +71,7 @@ class FormatterTest extends TestCase ...@@ -71,7 +71,7 @@ class FormatterTest extends TestCase
$value = time(); $value = time();
$this->assertSame(date('M j, Y', $value), $this->formatter->format($value, 'date')); $this->assertSame(date('M j, Y', $value), $this->formatter->format($value, 'date'));
$this->assertSame(date('M j, Y', $value), $this->formatter->format($value, 'DATE')); $this->assertSame(date('M j, Y', $value), $this->formatter->format($value, 'DATE'));
$this->assertSame(date('Y/m/d', $value), $this->formatter->format($value, ['date', 'Y/m/d'])); $this->assertSame(date('Y/m/d', $value), $this->formatter->format($value, ['date', 'php:Y/m/d']));
$this->setExpectedException('\yii\base\InvalidParamException'); $this->setExpectedException('\yii\base\InvalidParamException');
$this->assertSame(date('Y-m-d', $value), $this->formatter->format($value, 'data')); $this->assertSame(date('Y-m-d', $value), $this->formatter->format($value, 'data'));
} }
...@@ -195,7 +195,7 @@ class FormatterTest extends TestCase ...@@ -195,7 +195,7 @@ class FormatterTest extends TestCase
// public function testSetLocale(){ // public function testSetLocale(){
// $value = '12300'; // $value = '12300';
// $this->formatter->setLocale('de-DE'); // $this->formatter->setLocale('de-DE');
// $this->assertSame('12.300,00', $this->formatter->asDouble($value, 2)); // $this->assertSame('12.300,00', $this->formatter->asDecimal($value, 2));
// $value = time(); // $value = time();
// $this->assertSame(date('d.m.Y', $value), $this->formatter->asDate($value)); // $this->assertSame(date('d.m.Y', $value), $this->formatter->asDate($value));
// $this->formatter->setLocale('en-US'); // $this->formatter->setLocale('en-US');
...@@ -226,8 +226,10 @@ class FormatterTest extends TestCase ...@@ -226,8 +226,10 @@ class FormatterTest extends TestCase
$value = time(); $value = time();
$this->assertSame(date('M j, Y', $value), $this->formatter->asDate($value)); $this->assertSame(date('M j, Y', $value), $this->formatter->asDate($value));
$this->assertSame(date('Y/m/d', $value), $this->formatter->asDate($value, 'php:Y/m/d')); $this->assertSame(date('Y/m/d', $value), $this->formatter->asDate($value, 'php:Y/m/d'));
$this->assertSame(date('n/j/y', $value), $this->formatter->asDate($value, 'short')); $this->assertSame(date('d.m.Y', $value), $this->formatter->asDate($value, 'short'));
$this->assertSame(date('F j, Y', $value), $this->formatter->asDate($value, 'long')); $this->assertSame(date('F j, Y', $value), $this->formatter->asDate($value, 'long'));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asDate(null)); $this->assertSame($this->formatter->nullDisplay, $this->formatter->asDate(null));
} }
...@@ -236,6 +238,8 @@ class FormatterTest extends TestCase ...@@ -236,6 +238,8 @@ class FormatterTest extends TestCase
$value = time(); $value = time();
$this->assertSame(date('g:i:s A', $value), $this->formatter->asTime($value)); $this->assertSame(date('g:i:s A', $value), $this->formatter->asTime($value));
$this->assertSame(date('n:i:s A', $value), $this->formatter->asTime($value, 'php:n:i:s A')); $this->assertSame(date('n:i:s A', $value), $this->formatter->asTime($value, 'php:n:i:s A'));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asTime(null)); $this->assertSame($this->formatter->nullDisplay, $this->formatter->asTime(null));
} }
...@@ -244,6 +248,8 @@ class FormatterTest extends TestCase ...@@ -244,6 +248,8 @@ class FormatterTest extends TestCase
$value = time(); $value = time();
$this->assertSame(date('M j, Y g:i:s A', $value), $this->formatter->asDatetime($value)); $this->assertSame(date('M j, Y g:i:s A', $value), $this->formatter->asDatetime($value));
$this->assertSame(date('Y/m/d h:i:s A', $value), $this->formatter->asDatetime($value, 'php:Y/m/d h:i:s A')); $this->assertSame(date('Y/m/d h:i:s A', $value), $this->formatter->asDatetime($value, 'php:Y/m/d h:i:s A'));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asDatetime(null)); $this->assertSame($this->formatter->nullDisplay, $this->formatter->asDatetime(null));
} }
...@@ -255,6 +261,7 @@ class FormatterTest extends TestCase ...@@ -255,6 +261,7 @@ class FormatterTest extends TestCase
$this->assertSame("$value", $this->formatter->asTimestamp(date('Y-m-d H:i:s', $value))); $this->assertSame("$value", $this->formatter->asTimestamp(date('Y-m-d H:i:s', $value)));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asTimestamp(null)); $this->assertSame($this->formatter->nullDisplay, $this->formatter->asTimestamp(null));
} }
...@@ -382,105 +389,174 @@ class FormatterTest extends TestCase ...@@ -382,105 +389,174 @@ class FormatterTest extends TestCase
$dateThen = new DateTime('2014-03-31'); $dateThen = new DateTime('2014-03-31');
$this->assertSame('in a month', $this->formatter->asRelativeTime($this->buildDateSubIntervals('2014-03-03', [$interval_1_month]), $dateNow)); $this->assertSame('in a month', $this->formatter->asRelativeTime($this->buildDateSubIntervals('2014-03-03', [$interval_1_month]), $dateNow));
$this->assertSame('in 28 days', $this->formatter->asRelativeTime($dateThen, $dateNow)); $this->assertSame('in 28 days', $this->formatter->asRelativeTime($dateThen, $dateNow));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asRelativeTime(null));
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asRelativeTime(null, time()));
} }
// number format // number format
// public function testAsInteger() public function testIntlAsInteger()
// { {
// $value = 123; $this->testAsInteger();
// $this->assertSame("$value", $this->formatter->asInteger($value)); }
// $value = 123.23;
// $this->assertSame("123", $this->formatter->asInteger($value)); public function testAsInteger()
// $value = 'a'; {
// $this->assertSame("0", $this->formatter->asInteger($value)); $this->assertSame("123", $this->formatter->asInteger(123));
// $value = -123.23; $this->assertSame("123", $this->formatter->asInteger(123.23));
// $this->assertSame("-123", $this->formatter->asInteger($value)); $this->assertSame("123", $this->formatter->asInteger(123.53));
// $value = "-123abc"; $this->assertSame("0", $this->formatter->asInteger(0));
// $this->assertSame("-123", $this->formatter->asInteger($value)); $this->assertSame("0", $this->formatter->asInteger('a'));
// $this->assertSame($this->formatter->nullDisplay, $this->formatter->asInteger(null)); $this->assertSame("-123", $this->formatter->asInteger(-123.23));
// } $this->assertSame("-123", $this->formatter->asInteger(-123.53));
// $this->assertSame("-123", $this->formatter->asInteger("-123abc"));
// public function testAsDouble()
// { $this->assertSame("123,456", $this->formatter->asInteger(123456));
// $value = 123.12; $this->assertSame("123,456", $this->formatter->asInteger(123456.789));
// $this->assertSame("123.12", $this->formatter->asDouble($value));
// $this->assertSame("123.1", $this->formatter->asDouble($value, 1)); // null display
// $this->assertSame("123", $this->formatter->asDouble($value, 0)); $this->assertSame($this->formatter->nullDisplay, $this->formatter->asInteger(null));
// $value = 123; }
// $this->assertSame("123.00", $this->formatter->asDouble($value));
// $this->formatter->decimalSeparator = ','; public function testIntlAsDecimal()
// $this->formatter->thousandSeparator = '.'; {
// $value = 123.12; $this->testAsDecimal();
// $this->assertSame("123,12", $this->formatter->asDouble($value)); }
// $this->assertSame("123,1", $this->formatter->asDouble($value, 1));
// $this->assertSame("123", $this->formatter->asDouble($value, 0)); public function testAsDecimal()
// $value = 123123.123; {
// $this->assertSame("123.123,12", $this->formatter->asDouble($value)); $value = 123.12;
// $this->assertSame("123123,12", $this->formatter->asDouble($value, 2, null, false)); $this->assertSame("123.12", $this->formatter->asDecimal($value));
// $this->assertSame($this->formatter->nullDisplay, $this->formatter->asDouble(null)); $this->assertSame("123.1", $this->formatter->asDecimal($value, 1));
// } $this->assertSame("123", $this->formatter->asDecimal($value, 0));
// $value = 123;
// public function testAsNumber() $this->assertSame("123.00", $this->formatter->asDecimal($value));
// { $this->formatter->decimalSeparator = ',';
// $value = 123123.123; $this->formatter->thousandSeparator = '.';
// $this->assertSame("123,123", $this->formatter->asNumber($value)); $value = 123.12;
// $this->assertSame("123,123.12", $this->formatter->asNumber($value, 2)); $this->assertSame("123,12", $this->formatter->asDecimal($value));
// $this->formatter->decimalSeparator = ','; $this->assertSame("123,1", $this->formatter->asDecimal($value, 1));
// $this->formatter->thousandSeparator = ' '; $this->assertSame("123", $this->formatter->asDecimal($value, 0));
// $this->assertSame("123 123", $this->formatter->asNumber($value)); $value = 123123.123;
// $this->assertSame("123 123,12", $this->formatter->asNumber($value, 2)); $this->assertSame("123.123,12", $this->formatter->asDecimal($value));
// $this->formatter->thousandSeparator = ''; $this->assertSame("123123,12", $this->formatter->asDecimal($value, 2, null, false));
// $this->assertSame("123123", $this->formatter->asNumber($value));
// $this->assertSame("123123,12", $this->formatter->asNumber($value, 2)); $value = 123123.123;
// $this->assertSame($this->formatter->nullDisplay, $this->formatter->asNumber(null)); $this->assertSame("123,123", $this->formatter->asDecimal($value));
// } $this->assertSame("123,123.12", $this->formatter->asDecimal($value, 2));
// $this->formatter->decimalSeparator = ',';
// public function testAsDecimal() $this->formatter->thousandSeparator = ' ';
// { $this->assertSame("123 123", $this->formatter->asDecimal($value));
// $value = '123'; $this->assertSame("123 123,12", $this->formatter->asDecimal($value, 2));
// $this->assertSame($value, $this->formatter->asDecimal($value)); $this->formatter->thousandSeparator = '';
// $value = '123456'; $this->assertSame("123123", $this->formatter->asDecimal($value));
// $this->assertSame("123,456", $this->formatter->asDecimal($value)); $this->assertSame("123123,12", $this->formatter->asDecimal($value, 2));
// $value = '-123456.123';
// $this->assertSame("-123,456.123", $this->formatter->asDecimal($value)); $value = '-123456.123';
// $this->assertSame($this->formatter->nullDisplay, $this->formatter->asDecimal(null)); $this->assertSame("-123,456.123", $this->formatter->asDecimal($value));
// }
// // null display
// public function testAsCurrency() $this->assertSame($this->formatter->nullDisplay, $this->formatter->asDecimal(null));
// { }
// $value = '123';
// $this->assertSame('$123.00', $this->formatter->asCurrency($value)); public function testIntlAsPercent()
// $value = '123.456'; {
// $this->assertSame("$123.46", $this->formatter->asCurrency($value)); $this->testAsPercent();
// // Starting from ICU 52.1, negative currency value will be formatted as -$123,456.12 }
// // see: http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source/data/locales/en.txt
//// $value = '-123456.123'; public function testAsPercent()
//// $this->assertSame("($123,456.12)", $this->formatter->asCurrency($value)); {
// $this->assertSame($this->formatter->nullDisplay, $this->formatter->asCurrency(null)); $value = '123';
// } $this->assertSame('12,300%', $this->formatter->asPercent($value));
// $value = '0.1234';
// public function testAsScientific() $this->assertSame("12%", $this->formatter->asPercent($value));
// { $value = '-0.009343';
// $value = '123'; $this->assertSame("-1%", $this->formatter->asPercent($value));
// $this->assertSame('1.23E2', $this->formatter->asScientific($value));
// $value = '123456'; // null display
// $this->assertSame("1.23456E5", $this->formatter->asScientific($value)); $this->assertSame($this->formatter->nullDisplay, $this->formatter->asPercent(null));
// $value = '-123456.123'; }
// $this->assertSame("-1.23456123E5", $this->formatter->asScientific($value));
// $this->assertSame($this->formatter->nullDisplay, $this->formatter->asScientific(null)); public function testIntlAsCurrency()
// } {
// $this->testAsCurrency();
// public function testAsPercent() }
// {
// $value = '123'; public function testAsCurrency()
// $this->assertSame('12,300%', $this->formatter->asPercent($value)); {
// $value = '0.1234'; $value = '123';
// $this->assertSame("12%", $this->formatter->asPercent($value)); $this->assertSame('$123.00', $this->formatter->asCurrency($value));
// $value = '-0.009343'; $value = '123.456';
// $this->assertSame("-1%", $this->formatter->asPercent($value)); $this->assertSame("$123.46", $this->formatter->asCurrency($value));
// $this->assertSame($this->formatter->nullDisplay, $this->formatter->asPercent(null)); // Starting from ICU 52.1, negative currency value will be formatted as -$123,456.12
// } // see: http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source/data/locales/en.txt
// $value = '-123456.123';
// $this->assertSame("($123,456.12)", $this->formatter->asCurrency($value));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asCurrency(null));
}
public function testIntlAsScientific()
{
$this->testAsScientific();
}
public function testAsScientific()
{
$value = '123';
$this->assertSame('1.23E2', $this->formatter->asScientific($value));
$value = '123456';
$this->assertSame("1.23456E5", $this->formatter->asScientific($value));
$value = '-123456.123';
$this->assertSame("-1.23456123E5", $this->formatter->asScientific($value));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asScientific(null));
}
public function testIntlAsSpellout()
{
$this->assertSame('one hundred twenty-three', $this->formatter->asSpellout(123));
$this->formatter->locale = 'de_DE';
$this->assertSame('ein­hundert­drei­und­zwanzig', $this->formatter->asSpellout(123));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asSpellout(null));
}
public function testIntlAsOrdinal()
{
$this->assertSame('0th', $this->formatter->asOrdinal(0));
$this->assertSame('1st', $this->formatter->asOrdinal(1));
$this->assertSame('2nd', $this->formatter->asOrdinal(2));
$this->assertSame('3rd', $this->formatter->asOrdinal(3));
$this->assertSame('5th', $this->formatter->asOrdinal(5));
$this->formatter->locale = 'de_DE';
$this->assertSame('0.', $this->formatter->asOrdinal(0));
$this->assertSame('1.', $this->formatter->asOrdinal(1));
$this->assertSame('2.', $this->formatter->asOrdinal(2));
$this->assertSame('3.', $this->formatter->asOrdinal(3));
$this->assertSame('5.', $this->formatter->asOrdinal(5));
// null display
$this->assertSame($this->formatter->nullDisplay, $this->formatter->asOrdinal(null));
}
public function testIntlAsSize()
{
$this->testAsSize();
}
public function testAsSize()
{
// TODO
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment