包 | 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当前支持货币格式,百分比格式和十进制格式,还有通用格式。 前三种格式在区域数据里面指定, 通用格式允许你输入一些任意格式字符串。
一个格式化字符串可以由以下指定的字符组成:
任何周边模式(子模式)会被保留
以下是一些例子:
CNumberFormatter 尝试unicode Technical Standard #35实现数字格式化。 未实现以下功能:
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']>0 && 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;
}
解析指定的字符串模式。
参见
- formatNumber