CNumberFormatter


system.i18n
继承 class CNumberFormatter » CComponent
源自 1.0
版本 $Id: CNumberFormatter.php 2798 2011-01-01 19:29:03Z qiang.xue $
源码
CNumberFormatter提供数字转换为本地化功能。

CNumberFormatter格式化一个数字(integer或者float),然后输出基于指定格式的字符串。 一个 CNumberFormatter 实例跟一个区域关联, 因此生成的字符串反映了相关区域的使用方式。

CNumberFormatter当前支持货币格式,百分比格式和十进制格式,还有通用格式。 前三种格式在区域数据里面指定, 通用格式允许你输入一些任意格式字符串。

一个格式化字符串可以由以下指定的字符组成:
  • 点(.):十进制标点。可以替换成本地化的十进制标点。
  • 逗号(,):组的分隔符。它可以替换成本地化的组分隔符。
  • 零(0):必需的数字。 这个用来指定数字出现在哪个位置(以0为首位,或者没有)。
  • 哈希(#):可选数字。这个主要是用来指定十进制点和组分隔符的位置。
  • 货币(¤):金钱占位符。它可以替换成本地化的金钱符号。
  • 百分号(%):百分号。如果它出现,那么在格式化这个数字之前先除以100。
  • 千分号(‰):千分号。如果它出现,那么在格式化这个数字之前先除以1000。
  • 分号(;):正数和负数的子模式的字符分隔。


任何周边模式(子模式)会被保留

以下是一些例子:
模式 “#,##0.00” 会将 12345.678 格式化成 “12,345.68”。
模式 “#,#,#0.00” 会将 12345.6 格式化成 “1,2,3,45.60”。
注意,在第一个例子里,先应用格式再对数字进行四舍五入。 第二个例子,模式指定了两个分组大小。

CNumberFormatter 尝试Unicode Technical Standard #35实现数字格式化。 未实现以下功能:
  • 显著位数
  • 科学计算法
  • 任意文字字符
  • 任意填充

公共方法

方法 描述 定义在
__call() 如果类中没有调的方法名,则调用这个方法。 CComponent
__construct() 构造函数。 CNumberFormatter
__get() 返回一个属性值、一个事件处理程序列表或一个行为名称。 CComponent
__isset() 检查一个属性是否为null。 CComponent
__set() 设置一个组件的属性值。 CComponent
__unset() 设置一个组件的属性为null。 CComponent
asa() 返回这个名字的行为对象。 CComponent
attachBehavior() 附加一个行为到组件。 CComponent
attachBehaviors() 附加一个行为列表到组件。 CComponent
attachEventHandler() 为事件附加一个事件处理程序。 CComponent
canGetProperty() 确定属性是否可读。 CComponent
canSetProperty() 确定属性是否可写。 CComponent
detachBehavior() 从组件中分离一个行为。 CComponent
detachBehaviors() 从组件中分离所有行为。 CComponent
detachEventHandler() 分离一个存在的事件处理程序。 CComponent
disableBehavior() 禁用一个附加行为。 CComponent
disableBehaviors() 禁用组件附加的所有行为。 CComponent
enableBehavior() 启用一个附加行为。 CComponent
enableBehaviors() 启用组件附加的所有行为。 CComponent
evaluateExpression() 计算一个PHP表达式,或根据组件上下文执行回调。 CComponent
format() 基于指定模式格式化数字。 CNumberFormatter
formatCurrency() 使用本地化的货币格式来格式化数字。 CNumberFormatter
formatDecimal() 使用本地化的十进制格式来格式化数字。 CNumberFormatter
formatPercentage() 使用本地化的百分比格式来格式化数字。 CNumberFormatter
getEventHandlers() 返回一个事件的附加处理程序列表。 CComponent
hasEvent() 确定一个事件是否定义。 CComponent
hasEventHandler() 检查事件是否有附加的处理程序。 CComponent
hasProperty() 确定属性是否被定义。 CComponent
raiseEvent() 发起一个事件。 CComponent

受保护方法

方法 描述 定义在
formatNumber() 基于一个格式来格式化数字。 CNumberFormatter
parseFormat() 解析指定的字符串模式。 CNumberFormatter

方法详细

__construct() 方法
public void __construct(mixed $locale)
$locale mixed 本地化ID(字符串)或者CLocale的实例
public function __construct($locale)
{
    if(
is_string($locale))
        
$this->_locale=CLocale::getInstance($locale);
    else
        
$this->_locale=$locale;
}

构造函数。

format() 方法
public string format(string $pattern, mixed $value, string $currency=NULL)
$pattern string 格式模式
$value mixed 要格式化的数字
$currency string 3个字母的ISO 4217码。例如:“USD”代表美元,“EUR”代表欧元。 模式中的货币点位符将会被替换成货币符号。 如果为null,将不做更改。
{return} string 格式化结果。
public function format($pattern,$value,$currency=null)
{
    
$format=$this->parseFormat($pattern);
    
$result=$this->formatNumber($format,$value);
    if(
$currency===null)
        return 
$result;
    else if((
$symbol=$this->_locale->getCurrencySymbol($currency))===null)
        
$symbol=$currency;
    return 
str_replace('¤',$symbol,$result);
}

基于指定模式格式化数字。 注意,如果格式中中包含‘%’,数字首先除以100。 如果格式中包含‘‰’,数字首先除以1000。 如果格式中包含货币点位符, 它将会替换成本地化指定的货币点位符。

formatCurrency() 方法
public string formatCurrency(mixed $value, string $currency)
$value mixed 要格式化的数字
$currency string 3个字母的ISO 4217码。例如:“USD”代表美元,“EUR”代表欧元。 模式中的货币点位符将会被替换成货币符号。
{return} string 格式化结果。
public function formatCurrency($value,$currency)
{
    return 
$this->format($this->_locale->getCurrencyFormat(),$value,$currency);
}

使用本地化的货币格式来格式化数字。

formatDecimal() 方法
public string formatDecimal(mixed $value)
$value mixed 要格式化的数字
{return} string 格式化结果。
public function formatDecimal($value)
{
    return 
$this->format($this->_locale->getDecimalFormat(),$value);
}

使用本地化的十进制格式来格式化数字。

formatNumber() 方法
protected string formatNumber(array $format, mixed $value)
$format array 格式化的结构如下:
array(
	'decimalDigits'=>2,     // 小数点后所需要的数字位数;如果没有足够的位数将用0来填充;如果为-1,意味着我们会放弃小数点。
 'maxDecimalDigits'=>3,  // 小数点后数字的最大位数。多出来的位数将被截取。
	'integerDigits'=>1,     // 小数点后所需的位数的号码;如果没有足够的位数将用0来填充。
	'groupSize1'=>3,        // 主分组的大小;如果为0,意味着没有分组。
	'groupSize2'=>0,        // 第二分级的大小;如果为0,意味着没有第二分组。
	'positivePrefix'=>'+',  // 正数前缀
	'positiveSuffix'=>'',   // 正数后缀
	'negativePrefix'=>'(',  // 负数前缀
	'negativeSuffix'=>')',  // 负数后缀
	'multiplier'=>1,        // 100为百分比,1000为千分比。
);
$value mixed 要格式化的数字
{return} string 格式化结果
protected function formatNumber($format,$value)
{
    
$negative=$value<0;
    
$value=abs($value*$format['multiplier']);
    if(
$format['maxDecimalDigits']>=0)
        
$value=round($value,$format['maxDecimalDigits']);
    
$value="$value";
    if((
$pos=strpos($value,'.'))!==false)
    {
        
$integer=substr($value,0,$pos);
        
$decimal=substr($value,$pos+1);
    }
    else
    {
        
$integer=$value;
        
$decimal='';
    }

    if(
$format['decimalDigits']>strlen($decimal))
        
$decimal=str_pad($decimal,$format['decimalDigits'],'0');
    if(
strlen($decimal)>0)
        
$decimal=$this->_locale->getNumberSymbol('decimal').$decimal;

    
$integer=str_pad($integer,$format['integerDigits'],'0',STR_PAD_LEFT);
    if(
$format['groupSize1']>&& strlen($integer)>$format['groupSize1'])
    {
        
$str1=substr($integer,0,-$format['groupSize1']);
        
$str2=substr($integer,-$format['groupSize1']);
        
$size=$format['groupSize2']>0?$format['groupSize2']:$format['groupSize1'];
        
$str1=str_pad($str1,(int)((strlen($str1)+$size-1)/$size)*$size,' ',STR_PAD_LEFT);
        
$integer=ltrim(implode($this->_locale->getNumberSymbol('group'),str_split($str1,$size))).$this->_locale->getNumberSymbol('group').$str2;
    }

    if(
$negative)
        
$number=$format['negativePrefix'].$integer.$decimal.$format['negativeSuffix'];
    else
        
$number=$format['positivePrefix'].$integer.$decimal.$format['positiveSuffix'];

    return 
strtr($number,array('%'=>$this->_locale->getNumberSymbol('percentSign'),'‰'=>$this->_locale->getNumberSymbol('perMille')));
}

基于一个格式来格式化数字。 这个方法只格式化纯数字。

formatPercentage() 方法
public string formatPercentage(mixed $value)
$value mixed 要格式化的数字
{return} string 格式化结果。
public function formatPercentage($value)
{
    return 
$this->format($this->_locale->getPercentFormat(),$value);
}

使用本地化的百分比格式来格式化数字。 注意,如果格式中中包含‘%’,数字首先除以100。 如果格式中包含‘‰’,数字首先除以1000。

parseFormat() 方法
protected array parseFormat(string $pattern)
$pattern string 要解析的模式
{return} array 返回已经解析的模式
protected function parseFormat($pattern)
{
    if(isset(
$this->_formats[$pattern]))
        return 
$this->_formats[$pattern];

    
$format=array();

    
// find out prefix and suffix for positive and negative patterns
    
$patterns=explode(';',$pattern);
    
$format['positivePrefix']=$format['positiveSuffix']=$format['negativePrefix']=$format['negativeSuffix']='';
    if(
preg_match('/^(.*?)[#,\.0]+(.*?)$/',$patterns[0],$matches))
    {
        
$format['positivePrefix']=$matches[1];
        
$format['positiveSuffix']=$matches[2];
    }

    if(isset(
$patterns[1]) && preg_match('/^(.*?)[#,\.0]+(.*?)$/',$patterns[1],$matches))  // with a negative pattern
    
{
        
$format['negativePrefix']=$matches[1];
        
$format['negativeSuffix']=$matches[2];
    }
    else
    {
        
$format['negativePrefix']=$this->_locale->getNumberSymbol('minusSign').$format['positivePrefix'];
        
$format['negativeSuffix']=$format['positiveSuffix'];
    }
    
$pat=$patterns[0];

    
// find out multiplier
    
if(strpos($pat,'%')!==false)
        
$format['multiplier']=100;
    else if(
strpos($pat,'‰')!==false)
        
$format['multiplier']=1000;
    else
        
$format['multiplier']=1;

    
// find out things about decimal part
    
if(($pos=strpos($pat,'.'))!==false)
    {
        if((
$pos2=strrpos($pat,'0'))>$pos)
            
$format['decimalDigits']=$pos2-$pos;
        else
            
$format['decimalDigits']=0;
        if((
$pos3=strrpos($pat,'#'))>=$pos2)
            
$format['maxDecimalDigits']=$pos3-$pos;
        else
            
$format['maxDecimalDigits']=$format['decimalDigits'];
        
$pat=substr($pat,0,$pos);
    }
    else   
// no decimal part
    
{
        
$format['decimalDigits']=0;
        
$format['maxDecimalDigits']=0;
    }

    
// find out things about integer part
    
$p=str_replace(',','',$pat);
    if((
$pos=strpos($p,'0'))!==false)
        
$format['integerDigits']=strrpos($p,'0')-$pos+1;
    else
        
$format['integerDigits']=0;
    
// find out group sizes. some patterns may have two different group sizes
    
$p=str_replace('#','0',$pat);
    if((
$pos=strrpos($pat,','))!==false)
    {
        
$format['groupSize1']=strrpos($p,'0')-$pos;
        if((
$pos2=strrpos(substr($p,0,$pos),','))!==false)
            
$format['groupSize2']=$pos-$pos2-1;
        else
            
$format['groupSize2']=0;
    }
    else
        
$format['groupSize1']=$format['groupSize2']=0;

    return 
$this->_formats[$pattern]=$format;
}

解析指定的字符串模式。

参见