Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** sfNumberFormatInfo class file.** This program is free software; you can redistribute it and/or modify* it under the terms of the BSD License.** Copyright(c) 2004 by Qiang Xue. All rights reserved.** To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}* The latest version of PRADO can be obtained from:* {@link http://prado.sourceforge.net/}** @author Wei Zhuo <weizhuo[at]gmail[dot]com>* @version $Id: sfNumberFormatInfo.class.php 28725 2010-03-23 16:56:48Z FabianLange $* @package symfony* @subpackage i18n*//*** sfNumberFormatInfo class** Defines how numeric values are formatted and displayed,* depending on the culture. Numeric values are formatted using* standard or custom patterns stored in the properties of a* sfNumberFormatInfo.** This class contains information, such as currency, decimal* separators, and other numeric symbols.** To create a sfNumberFormatInfo for a specific culture,* create a sfCultureInfo for that culture and retrieve the* sfCultureInfo->NumberFormat property. Or use* sfNumberFormatInfo::getInstance($culture).* To create a sfNumberFormatInfo for the invariant culture, use the* InvariantInfo::getInvariantInfo().*** @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>* @version v1.0, last update on Sun Dec 05 14:48:26 EST 2004* @package symfony* @subpackage i18n*/class sfNumberFormatInfo{/*** ICU number formatting data.* @var array*/protected $data = array();/*** A list of properties that are accessable/writable.* @var array*/protected $properties = array();/*** The number pattern.* @var array*/protected $pattern = array();const DECIMAL = 0;const CURRENCY = 1;const PERCENTAGE = 2;const SCIENTIFIC = 3;/*** Allows functions that begins with 'set' to be called directly* as an attribute/property to retrieve the value.** @return mixed*/function __get($name){$getProperty = 'get'.$name;if (in_array($getProperty, $this->properties)){return $this->$getProperty();}else{throw new sfException(sprintf('Property %s does not exists.', $name));}}/*** Allows functions that begins with 'set' to be called directly* as an attribute/property to set the value.*/function __set($name, $value){$setProperty = 'set'.$name;if (in_array($setProperty, $this->properties)){$this->$setProperty($value);}else{throw new sfException(sprintf('Property %s can not be set.', $name));}}/*** Initializes a new writable instance of the sfNumberFormatInfo class* that is dependent on the ICU data for number, decimal, and currency* formatting information. <b>N.B.</b>You should not initialize this* class directly unless you know what you are doing. Please use use* sfNumberFormatInfo::getInstance() to create an instance.** @param array $data ICU data for date time formatting.* @param int $type The sfNumberFormatInfo type* @see getInstance()*/function __construct($data = array(), $type = sfNumberFormatInfo::DECIMAL){$this->properties = get_class_methods($this);if (empty($data)){throw new sfException('Please provide the ICU data to initialize.');}$this->data = $data;$this->setPattern($type);}/*** Sets the pattern for a specific number pattern. The validate patterns* sfNumberFormatInfo::DECIMAL, sfNumberFormatInfo::CURRENCY,* sfNumberFormatInfo::PERCENTAGE, or sfNumberFormatInfo::SCIENTIFIC** @param int $type pattern type.*/function setPattern($type = sfNumberFormatInfo::DECIMAL){if (is_int($type)){$this->pattern = $this->parsePattern($this->data['NumberPatterns'][$type]);}else{$this->pattern = $this->parsePattern($type);}$this->pattern['negInfty'] = $this->data['NumberElements'][6].$this->data['NumberElements'][9];$this->pattern['posInfty'] = $this->data['NumberElements'][11].$this->data['NumberElements'][9];}function getPattern(){return $this->pattern;}/*** Gets the default sfNumberFormatInfo that is culture-independent (invariant).** @return sfNumberFormatInfo default sfNumberFormatInfo.*/static public function getInvariantInfo($type = sfNumberFormatInfo::DECIMAL){static $invariant;if (null === $invariant){$culture = sfCultureInfo::getInvariantCulture();$invariant = $culture->NumberFormat;$invariant->setPattern($type);}return $invariant;}/*** Returns the sfNumberFormatInfo associated with the specified culture.** @param sfCultureInfo $culture the culture that gets the sfNumberFormat property.* @param int $type the number formatting type, it should be* sfNumberFormatInfo::DECIMAL, sfNumberFormatInfo::CURRENCY,* sfNumberFormatInfo::PERCENTAGE, or sfNumberFormatInfo::SCIENTIFIC* @return sfNumberFormatInfo sfNumberFormatInfo for the specified culture.* @see getCurrencyInstance();* @see getPercentageInstance();* @see getScientificInstance();*/public static function getInstance($culture = null, $type = sfNumberFormatInfo::DECIMAL){if ($culture instanceof sfCultureInfo){$formatInfo = $culture->getNumberFormat();$formatInfo->setPattern($type);return $formatInfo;}else if (is_string($culture)){$sfCultureInfo = sfCultureInfo::getInstance($culture);$formatInfo = $sfCultureInfo->getNumberFormat();$formatInfo->setPattern($type);return $formatInfo;}else{$sfCultureInfo = sfCultureInfo::getInstance();$formatInfo = $sfCultureInfo->getNumberFormat();$formatInfo->setPattern($type);return $formatInfo;}}/*** Returns the currency format info associated with the specified culture.** @param sfCultureInfo $culture the culture that gets the NumberFormat property.* @return sfNumberFormatInfo sfNumberFormatInfo for the specified culture.*/public static function getCurrencyInstance($culture = null){return self::getInstance($culture, self::CURRENCY);}/*** Returns the percentage format info associated with the specified culture.** @param sfCultureInfo $culture the culture that gets the NumberFormat property.* @return sfNumberFormatInfo sfNumberFormatInfo for the specified culture.*/public static function getPercentageInstance($culture = null){return self::getInstance($culture, self::PERCENTAGE);}/*** Returns the scientific format info associated with the specified culture.** @param sfCultureInfo $culture the culture that gets the NumberFormat property.* @return sfNumberFormatInfo sfNumberFormatInfo for the specified culture.*/public static function getScientificInstance($culture = null){return self::getInstance($culture, self::SCIENTIFIC);}/*** Parses the given pattern and return a list of known properties.** @param string $pattern a number pattern.* @return array list of pattern properties.*/protected function parsePattern($pattern){$pattern = explode(';', $pattern);$negative = null;if (count($pattern) > 1){$negative = $pattern[1];}$pattern = $pattern[0];$comma = ',';$dot = '.';$digit = '0';$hash = '#';// find the first group point, and decimal point$groupPos1 = strrpos($pattern, $comma);$decimalPos = strrpos($pattern, $dot);$groupPos2 = false;$groupSize1 = false;$groupSize2 = false;$decimalPoints = is_int($decimalPos) ? -1 : false;$info['negative'] = $negative;$info['positive'] = $pattern;$posfix = $this->getPrePostfix($pattern);$info['posPref'] = $posfix[0];$info['posPost'] = $posfix[1];if ($negative){// find the negative prefix and postfix$prefixPostfix = $this->getPrePostfix($negative);$info['negPref'] = $prefixPostfix[0];$info['negPost'] = $prefixPostfix[1];}else{// use the positive prefix and postfix and add the NegativeSign// http://www.unicode.org/reports/tr35/tr35-15.html#Number_Format_Patterns// If there is no explicit negative subpattern, the negative subpattern is the localized minus sign prefixed to the positive subpattern.$info['negPref'] = $this->getNegativeSign().$info['posPref'];$info['negPost'] = $info['posPost'];}if (is_int($groupPos1)){// get the second group$groupPos2 = strrpos(substr($pattern, 0, $groupPos1), $comma);// get the number of decimal digitsif (is_int($decimalPos)){$groupSize1 = $decimalPos - $groupPos1 - 1;}else{// no decimal point, so traverse from the back// to find the groupsize 1.for ($i = strlen($pattern) - 1; $i >= 0; $i--){if ($pattern{$i} == $digit || $pattern{$i} == $hash){$groupSize1 = $i - $groupPos1;break;}}}// get the second group sizeif (is_int($groupPos2)){$groupSize2 = $groupPos1 - $groupPos2 - 1;}}if (is_int($decimalPos)){for ($i = strlen($pattern) - 1; $i >= 0; $i--){if ($pattern{$i} == $dot){break;}if ($pattern{$i} == $digit){$decimalPoints = $i - $decimalPos;break;}}}$digitPattern = is_int($decimalPos) ? substr($pattern, 0, $decimalPos) : $pattern;$digitPattern = preg_replace('/[^0]/', '', $digitPattern);$info['groupPos1'] = $groupPos1;$info['groupSize1'] = $groupSize1;$info['groupPos2'] = $groupPos2;$info['groupSize2'] = $groupSize2;$info['decimalPos'] = $decimalPos;$info['decimalPoints'] = $decimalPoints;$info['digitSize'] = strlen($digitPattern);return $info;}/*** Gets the prefix and postfix of a pattern.** @param string $pattern pattern* @return array of prefix and postfix, array(prefix,postfix).*/protected function getPrePostfix($pattern){$regexp = '/[#,\.0]+/';$result = preg_split($regexp, $pattern);return array($result[0], $result[1]);}/*** Indicates the number of decimal places.** @return int number of decimal places.*/function getDecimalDigits(){return $this->pattern['decimalPoints'];}/*** Sets the number of decimal places.** @param int $value number of decimal places.*/function setDecimalDigits($value){return $this->pattern['decimalPoints'] = $value;}/*** Indicates the digit size.** @return int digit size.*/function getDigitSize(){return $this->pattern['digitSize'];}/*** Sets the digit size.** @param int $value digit size.*/function setDigitSize($value){$this->pattern['digitSize'] = $value;}/*** Gets the string to use as the decimal separator.** @return string decimal separator.*/function getDecimalSeparator(){return $this->data['NumberElements'][0];}/*** Sets the string to use as the decimal separator.** @param string $value the decimal point*/function setDecimalSeparator($value){return $this->data['NumberElements'][0] = $value;}/*** Gets the string that separates groups of digits to the left* of the decimal in currency values.** @return string currency group separator.*/function getGroupSeparator(){return $this->data['NumberElements'][1];}/*** Sets the string to use as the group separator.** @param string $value the group separator.*/function setGroupSeparator($value){return $this->data['NumberElements'][1] = $value;}/*** Gets the number of digits in each group to the left of the decimal* There can be two grouping sizes, this fucntion* returns <b>array(group1, group2)</b>, if there is only 1 grouping size,* group2 will be false.** @return array grouping size(s).*/function getGroupSizes(){$group1 = $this->pattern['groupSize1'];$group2 = $this->pattern['groupSize2'];return array($group1, $group2);}/*** Sets the number of digits in each group to the left of the decimal.* There can be two grouping sizes, the value should* be an <b>array(group1, group2)</b>, if there is only 1 grouping size,* group2 should be false.** @param array $groupSize grouping size(s).*/function setGroupSizes($groupSize){$this->pattern['groupSize1'] = $groupSize[0];$this->pattern['groupSize2'] = $groupSize[1];}/*** Gets the format pattern for negative values.* The negative pattern is composed of a prefix, and postfix.* This function returns <b>array(prefix, postfix)</b>.** @return arary negative pattern.*/function getNegativePattern(){$prefix = $this->pattern['negPref'];$postfix = $this->pattern['negPost'];return array($prefix, $postfix);}/*** Sets the format pattern for negative values.* The negative pattern is composed of a prefix, and postfix in the form* <b>array(prefix, postfix)</b>.** @param arary $pattern negative pattern.*/function setNegativePattern($pattern){$this->pattern['negPref'] = $pattern[0];$this->pattern['negPost'] = $pattern[1];}/*** Gets the format pattern for positive values.* The positive pattern is composed of a prefix, and postfix.* This function returns <b>array(prefix, postfix)</b>.** @return arary positive pattern.*/function getPositivePattern(){$prefix = $this->pattern['posPref'];$postfix = $this->pattern['posPost'];return array($prefix, $postfix);}/*** Sets the format pattern for positive values.* The positive pattern is composed of a prefix, and postfix in the form* <b>array(prefix, postfix)</b>.** @param arary $pattern positive pattern.*/function setPositivePattern($pattern){$this->pattern['posPref'] = $pattern[0];$this->pattern['posPost'] = $pattern[1];}/*** Gets the string to use as the currency symbol.** @return string $currency currency symbol.*/function getCurrencySymbol($currency = 'USD'){if (isset($this->pattern['symbol'])){return $this->pattern['symbol'];}else{return $this->data['Currencies'][$currency][0];}}/*** Sets the string to use as the currency symbol.** @param string $symbol currency symbol.*/function setCurrencySymbol($symbol){$this->pattern['symbol'] = $symbol;}/*** Gets the string that represents negative infinity.** @return string negative infinity.*/function getNegativeInfinitySymbol(){return $this->pattern['negInfty'];}/*** Sets the string that represents negative infinity.** @param string $value negative infinity.*/function setNegativeInfinitySymbol($value){$this->pattern['negInfty'] = $value;}/*** Gets the string that represents positive infinity.** @return string positive infinity.*/function getPositiveInfinitySymbol(){return $this->pattern['posInfty'];}/*** Sets the string that represents positive infinity.** @param string $value positive infinity.*/function setPositiveInfinitySymbol($value){$this->pattern['posInfty'] = $value;}/*** Gets the string that denotes that the associated number is negative.** @return string negative sign.*/function getNegativeSign(){return $this->data['NumberElements'][6];}/*** Sets the string that denotes that the associated number is negative.** @param string $value negative sign.*/function setNegativeSign($value){$this->data['NumberElements'][6] = $value;}/*** Gets the string that denotes that the associated number is positive.** @return string positive sign.*/function getPositiveSign(){return $this->data['NumberElements'][11];}/*** Sets the string that denotes that the associated number is positive.** @param string $value positive sign.*/function setPositiveSign($value){$this->data['NumberElements'][11] = $value;}/*** Gets the string that represents the IEEE NaN (not a number) value.** @return string NaN symbol.*/function getNaNSymbol(){return $this->data['NumberElements'][10];}/*** Sets the string that represents the IEEE NaN (not a number) value.** @param string $value NaN symbol.*/function setNaNSymbol($value){$this->data['NumberElements'][10] = $value;}/*** Gets the string to use as the percent symbol.** @return string percent symbol.*/function getPercentSymbol(){return $this->data['NumberElements'][3];}/*** Sets the string to use as the percent symbol.** @param string $value percent symbol.*/function setPercentSymbol($value){$this->data['NumberElements'][3] = $value;}/*** Gets the string to use as the per mille symbol.** @return string percent symbol.*/function getPerMilleSymbol(){return $this->data['NumberElements'][8];}/*** Sets the string to use as the per mille symbol.** @param string $value percent symbol.*/function setPerMilleSymbol($value){$this->data['NumberElements'][8] = $value;}}