Added new (clean) yii boilerplate
This commit is contained in:
559
framework/i18n/CDateFormatter.php
Normal file
559
framework/i18n/CDateFormatter.php
Normal file
@@ -0,0 +1,559 @@
|
||||
<?php
|
||||
/**
|
||||
* CDateFormatter class file.
|
||||
*
|
||||
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CDateFormatter provides date/time localization functionalities.
|
||||
*
|
||||
* CDateFormatter allows you to format dates and times in a locale-sensitive manner.
|
||||
* Patterns are interpreted in the locale that the CDateFormatter instance
|
||||
* is associated with. For example, month names and weekday names may vary
|
||||
* under different locales, which yields different formatting results.
|
||||
* The patterns that CDateFormatter recognizes are as defined in
|
||||
* {@link http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns CLDR}.
|
||||
*
|
||||
* CDateFormatter supports predefined patterns as well as customized ones:
|
||||
* <ul>
|
||||
* <li>The method {@link formatDateTime()} formats date or time or both using
|
||||
* predefined patterns which include 'full', 'long', 'medium' (default) and 'short'.</li>
|
||||
* <li>The method {@link format()} formats datetime using the specified pattern.
|
||||
* See {@link http://www.unicode.org/reports/tr35/#Date_Format_Patterns} for
|
||||
* details about the recognized pattern characters.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.i18n
|
||||
* @since 1.0
|
||||
*/
|
||||
class CDateFormatter extends CComponent
|
||||
{
|
||||
/**
|
||||
* @var array pattern characters mapping to the corresponding translator methods
|
||||
*/
|
||||
private static $_formatters=array(
|
||||
'G'=>'formatEra',
|
||||
'y'=>'formatYear',
|
||||
'M'=>'formatMonth',
|
||||
'L'=>'formatMonth',
|
||||
'd'=>'formatDay',
|
||||
'h'=>'formatHour12',
|
||||
'H'=>'formatHour24',
|
||||
'm'=>'formatMinutes',
|
||||
's'=>'formatSeconds',
|
||||
'E'=>'formatDayInWeek',
|
||||
'c'=>'formatDayInWeek',
|
||||
'e'=>'formatDayInWeek',
|
||||
'D'=>'formatDayInYear',
|
||||
'F'=>'formatDayInMonth',
|
||||
'w'=>'formatWeekInYear',
|
||||
'W'=>'formatWeekInMonth',
|
||||
'a'=>'formatPeriod',
|
||||
'k'=>'formatHourInDay',
|
||||
'K'=>'formatHourInPeriod',
|
||||
'z'=>'formatTimeZone',
|
||||
'Z'=>'formatTimeZone',
|
||||
'v'=>'formatTimeZone',
|
||||
);
|
||||
|
||||
private $_locale;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param mixed $locale locale ID (string) or CLocale instance
|
||||
*/
|
||||
public function __construct($locale)
|
||||
{
|
||||
if(is_string($locale))
|
||||
$this->_locale=CLocale::getInstance($locale);
|
||||
else
|
||||
$this->_locale=$locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a date according to a customized pattern.
|
||||
* @param string $pattern the pattern (See {@link http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns})
|
||||
* @param mixed $time UNIX timestamp or a string in strtotime format
|
||||
* @return string formatted date time. Null if $time is null. (the null value check is available since Yii 1.1.11)
|
||||
*/
|
||||
public function format($pattern,$time)
|
||||
{
|
||||
if($time===null)
|
||||
return null;
|
||||
|
||||
if(is_string($time))
|
||||
{
|
||||
if(ctype_digit($time) || ($time{0}=='-' && ctype_digit(substr($time, 1))))
|
||||
$time=(int)$time;
|
||||
else
|
||||
$time=strtotime($time);
|
||||
}
|
||||
$date=CTimestamp::getDate($time,false,false);
|
||||
$tokens=$this->parseFormat($pattern);
|
||||
foreach($tokens as &$token)
|
||||
{
|
||||
if(is_array($token)) // a callback: method name, sub-pattern
|
||||
$token=$this->{$token[0]}($token[1],$date);
|
||||
}
|
||||
return implode('',$tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a date according to a predefined pattern.
|
||||
* The predefined pattern is determined based on the date pattern width and time pattern width.
|
||||
* @param mixed $timestamp UNIX timestamp or a string in strtotime format
|
||||
* @param string $dateWidth width of the date pattern. It can be 'full', 'long', 'medium' and 'short'.
|
||||
* If null, it means the date portion will NOT appear in the formatting result
|
||||
* @param string $timeWidth width of the time pattern. It can be 'full', 'long', 'medium' and 'short'.
|
||||
* If null, it means the time portion will NOT appear in the formatting result
|
||||
* @return string formatted date time.
|
||||
*/
|
||||
public function formatDateTime($timestamp,$dateWidth='medium',$timeWidth='medium')
|
||||
{
|
||||
if(!empty($dateWidth))
|
||||
$date=$this->format($this->_locale->getDateFormat($dateWidth),$timestamp);
|
||||
|
||||
if(!empty($timeWidth))
|
||||
$time=$this->format($this->_locale->getTimeFormat($timeWidth),$timestamp);
|
||||
|
||||
if(isset($date) && isset($time))
|
||||
{
|
||||
$dateTimePattern=$this->_locale->getDateTimeFormat();
|
||||
return strtr($dateTimePattern,array('{0}'=>$time,'{1}'=>$date));
|
||||
}
|
||||
elseif(isset($date))
|
||||
return $date;
|
||||
elseif(isset($time))
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the datetime format pattern.
|
||||
* @param string $pattern the pattern to be parsed
|
||||
* @return array tokenized parsing result
|
||||
*/
|
||||
protected function parseFormat($pattern)
|
||||
{
|
||||
static $formats=array(); // cache
|
||||
if(isset($formats[$pattern]))
|
||||
return $formats[$pattern];
|
||||
$tokens=array();
|
||||
$n=strlen($pattern);
|
||||
$isLiteral=false;
|
||||
$literal='';
|
||||
for($i=0;$i<$n;++$i)
|
||||
{
|
||||
$c=$pattern[$i];
|
||||
if($c==="'")
|
||||
{
|
||||
if($i<$n-1 && $pattern[$i+1]==="'")
|
||||
{
|
||||
$tokens[]="'";
|
||||
$i++;
|
||||
}
|
||||
elseif($isLiteral)
|
||||
{
|
||||
$tokens[]=$literal;
|
||||
$literal='';
|
||||
$isLiteral=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$isLiteral=true;
|
||||
$literal='';
|
||||
}
|
||||
}
|
||||
elseif($isLiteral)
|
||||
$literal.=$c;
|
||||
else
|
||||
{
|
||||
for($j=$i+1;$j<$n;++$j)
|
||||
{
|
||||
if($pattern[$j]!==$c)
|
||||
break;
|
||||
}
|
||||
$p=str_repeat($c,$j-$i);
|
||||
if(isset(self::$_formatters[$c]))
|
||||
$tokens[]=array(self::$_formatters[$c],$p);
|
||||
else
|
||||
$tokens[]=$p;
|
||||
$i=$j-1;
|
||||
}
|
||||
}
|
||||
if($literal!=='')
|
||||
$tokens[]=$literal;
|
||||
|
||||
return $formats[$pattern]=$tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the year.
|
||||
* "yy" will return the last two digits of year.
|
||||
* "y...y" will pad the year with 0 in the front, e.g. "yyyyy" will generate "02008" for year 2008.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @return string formatted year
|
||||
*/
|
||||
protected function formatYear($pattern,$date)
|
||||
{
|
||||
$year=$date['year'];
|
||||
if($pattern==='yy')
|
||||
return str_pad($year%100,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
return str_pad($year,strlen($pattern),'0',STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the month.
|
||||
* "M" will return integer 1 through 12;
|
||||
* "MM" will return two digits month number with necessary zero padding, e.g. 05;
|
||||
* "MMM" will return the abrreviated month name, e.g. "Jan";
|
||||
* "MMMM" will return the full month name, e.g. "January";
|
||||
* "MMMMM" will return the narrow month name, e.g. "J";
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "month" pattern is unknown
|
||||
* @return string month name
|
||||
*/
|
||||
protected function formatMonth($pattern,$date)
|
||||
{
|
||||
$month=$date['mon'];
|
||||
switch($pattern)
|
||||
{
|
||||
case 'M':
|
||||
return $month;
|
||||
case 'MM':
|
||||
return str_pad($month,2,'0',STR_PAD_LEFT);
|
||||
case 'MMM':
|
||||
return $this->_locale->getMonthName($month,'abbreviated');
|
||||
case 'MMMM':
|
||||
return $this->_locale->getMonthName($month,'wide');
|
||||
case 'MMMMM':
|
||||
return $this->_locale->getMonthName($month,'narrow');
|
||||
case 'L':
|
||||
return $month;
|
||||
case 'LL':
|
||||
return str_pad($month,2,'0',STR_PAD_LEFT);
|
||||
case 'LLL':
|
||||
return $this->_locale->getMonthName($month,'abbreviated', true);
|
||||
case 'LLLL':
|
||||
return $this->_locale->getMonthName($month,'wide', true);
|
||||
case 'LLLLL':
|
||||
return $this->_locale->getMonthName($month,'narrow', true);
|
||||
default:
|
||||
throw new CException(Yii::t('yii','The pattern for month must be "M", "MM", "MMM", "MMMM", "L", "LL", "LLL" or "LLLL".'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the day of the month.
|
||||
* "d" for non-padding, "dd" will always return 2 digits day numbers, e.g. 05.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "day" pattern is unknown
|
||||
* @return string day of the month
|
||||
*/
|
||||
protected function formatDay($pattern,$date)
|
||||
{
|
||||
$day=$date['mday'];
|
||||
if($pattern==='d')
|
||||
return $day;
|
||||
elseif($pattern==='dd')
|
||||
return str_pad($day,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for day of the month must be "d" or "dd".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the day in the year, e.g. [1-366]
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException is "dayInYear" pattern is unknown
|
||||
* @return integer hours in AM/PM format.
|
||||
*/
|
||||
protected function formatDayInYear($pattern,$date)
|
||||
{
|
||||
$day=$date['yday'];
|
||||
if(($n=strlen($pattern))<=3)
|
||||
return str_pad($day,$n,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for day in year must be "D", "DD" or "DDD".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get day of week in the month, e.g. 2nd Wed in July.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "dayInMonth" pattern is unknown
|
||||
* @return integer day in month
|
||||
* @see http://www.unicode.org/reports/tr35/#Date_Format_Patterns
|
||||
*/
|
||||
protected function formatDayInMonth($pattern,$date)
|
||||
{
|
||||
if($pattern==='F')
|
||||
return (int)(($date['mday']+6)/7);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for day in month must be "F".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the day of the week.
|
||||
* "E", "EE", "EEE" will return abbreviated week day name, e.g. "Tues";
|
||||
* "EEEE" will return full week day name;
|
||||
* "EEEEE" will return the narrow week day name, e.g. "T";
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "dayInWeek" pattern is unknown
|
||||
* @return string day of the week.
|
||||
* @see http://www.unicode.org/reports/tr35/#Date_Format_Patterns
|
||||
*/
|
||||
protected function formatDayInWeek($pattern,$date)
|
||||
{
|
||||
$day=$date['wday'];
|
||||
switch($pattern)
|
||||
{
|
||||
case 'E':
|
||||
case 'EE':
|
||||
case 'EEE':
|
||||
case 'eee':
|
||||
return $this->_locale->getWeekDayName($day,'abbreviated');
|
||||
case 'EEEE':
|
||||
case 'eeee':
|
||||
return $this->_locale->getWeekDayName($day,'wide');
|
||||
case 'EEEEE':
|
||||
case 'eeeee':
|
||||
return $this->_locale->getWeekDayName($day,'narrow');
|
||||
case 'e':
|
||||
case 'ee':
|
||||
case 'c':
|
||||
return $day ? $day : 7;
|
||||
case 'ccc':
|
||||
return $this->_locale->getWeekDayName($day,'abbreviated',true);
|
||||
case 'cccc':
|
||||
return $this->_locale->getWeekDayName($day,'wide',true);
|
||||
case 'ccccc':
|
||||
return $this->_locale->getWeekDayName($day,'narrow',true);
|
||||
default:
|
||||
throw new CException(Yii::t('yii','The pattern for day of the week must be "E", "EE", "EEE", "EEEE", "EEEEE", "e", "ee", "eee", "eeee", "eeeee", "c", "cccc" or "ccccc".'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AM/PM designator, 12 noon is PM, 12 midnight is AM.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "period" pattern is unknown
|
||||
* @return string AM or PM designator
|
||||
*/
|
||||
protected function formatPeriod($pattern,$date)
|
||||
{
|
||||
if($pattern==='a')
|
||||
{
|
||||
if(intval($date['hours']/12))
|
||||
return $this->_locale->getPMName();
|
||||
else
|
||||
return $this->_locale->getAMName();
|
||||
}
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for AM/PM marker must be "a".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hours in 24 hour format, i.e. [0-23].
|
||||
* "H" for non-padding, "HH" will always return 2 characters.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "hour24" pattern is unknown
|
||||
* @return string hours in 24 hour format.
|
||||
*/
|
||||
protected function formatHour24($pattern,$date)
|
||||
{
|
||||
$hour=$date['hours'];
|
||||
if($pattern==='H')
|
||||
return $hour;
|
||||
elseif($pattern==='HH')
|
||||
return str_pad($hour,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for 24 hour format must be "H" or "HH".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hours in 12 hour format, i.e., [1-12]
|
||||
* "h" for non-padding, "hh" will always return 2 characters.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "hour12" pattern is unknown
|
||||
* @return string hours in 12 hour format.
|
||||
*/
|
||||
protected function formatHour12($pattern,$date)
|
||||
{
|
||||
$hour=$date['hours'];
|
||||
$hour=($hour==12|$hour==0)?12:($hour)%12;
|
||||
if($pattern==='h')
|
||||
return $hour;
|
||||
elseif($pattern==='hh')
|
||||
return str_pad($hour,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for 12 hour format must be "h" or "hh".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hours [1-24].
|
||||
* 'k' for non-padding, and 'kk' with 2 characters padding.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "hourInDay" pattern is unknown
|
||||
* @return integer hours [1-24]
|
||||
*/
|
||||
protected function formatHourInDay($pattern,$date)
|
||||
{
|
||||
$hour=$date['hours']==0?24:$date['hours'];
|
||||
if($pattern==='k')
|
||||
return $hour;
|
||||
elseif($pattern==='kk')
|
||||
return str_pad($hour,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for hour in day must be "k" or "kk".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hours in AM/PM format, e.g [0-11]
|
||||
* "K" for non-padding, "KK" will always return 2 characters.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "hourInPeriod" pattern is unknown
|
||||
* @return integer hours in AM/PM format.
|
||||
*/
|
||||
protected function formatHourInPeriod($pattern,$date)
|
||||
{
|
||||
$hour=$date['hours']%12;
|
||||
if($pattern==='K')
|
||||
return $hour;
|
||||
elseif($pattern==='KK')
|
||||
return str_pad($hour,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for hour in AM/PM must be "K" or "KK".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minutes.
|
||||
* "m" for non-padding, "mm" will always return 2 characters.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "minutes" pattern is unknown
|
||||
* @return string minutes.
|
||||
*/
|
||||
protected function formatMinutes($pattern,$date)
|
||||
{
|
||||
$minutes=$date['minutes'];
|
||||
if($pattern==='m')
|
||||
return $minutes;
|
||||
elseif($pattern==='mm')
|
||||
return str_pad($minutes,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for minutes must be "m" or "mm".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the seconds.
|
||||
* "s" for non-padding, "ss" will always return 2 characters.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "seconds" pattern is unknown
|
||||
* @return string seconds
|
||||
*/
|
||||
protected function formatSeconds($pattern,$date)
|
||||
{
|
||||
$seconds=$date['seconds'];
|
||||
if($pattern==='s')
|
||||
return $seconds;
|
||||
elseif($pattern==='ss')
|
||||
return str_pad($seconds,2,'0',STR_PAD_LEFT);
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for seconds must be "s" or "ss".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the week in the year.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "weekInYear" pattern is unknown
|
||||
* @return integer week in year
|
||||
*/
|
||||
protected function formatWeekInYear($pattern,$date)
|
||||
{
|
||||
if($pattern==='w')
|
||||
return @date('W',@mktime(0,0,0,$date['mon'],$date['mday'],$date['year']));
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for week in year must be "w".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get week in the month.
|
||||
* @param array $pattern result of {@link CTimestamp::getdate}.
|
||||
* @param string $date a pattern.
|
||||
* @throws CException if "weekInMonth" pattern is unknown
|
||||
* @return integer week in month
|
||||
*/
|
||||
protected function formatWeekInMonth($pattern,$date)
|
||||
{
|
||||
if($pattern==='W')
|
||||
{
|
||||
$weekDay=date('N',mktime(0,0,0,$date['mon'],1,$date['year']));
|
||||
return floor(($weekDay+$date['mday']-2)/7)+1;
|
||||
}
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for week in month must be "W".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the timezone of the server machine.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "timeZone" pattern is unknown
|
||||
* @return string time zone
|
||||
* @todo How to get the timezone for a different region?
|
||||
*/
|
||||
protected function formatTimeZone($pattern,$date)
|
||||
{
|
||||
if($pattern[0]==='z' || $pattern[0]==='v')
|
||||
return @date('T', @mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']));
|
||||
elseif($pattern[0]==='Z')
|
||||
return @date('O', @mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']));
|
||||
else
|
||||
throw new CException(Yii::t('yii','The pattern for time zone must be "z" or "v".'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the era. i.e. in gregorian, year > 0 is AD, else BC.
|
||||
* @param string $pattern a pattern.
|
||||
* @param array $date result of {@link CTimestamp::getdate}.
|
||||
* @throws CException if "era" pattern is unknown
|
||||
* @return string era
|
||||
* @todo How to support multiple Eras?, e.g. Japanese.
|
||||
*/
|
||||
protected function formatEra($pattern,$date)
|
||||
{
|
||||
$era=$date['year']>0 ? 1 : 0;
|
||||
switch($pattern)
|
||||
{
|
||||
case 'G':
|
||||
case 'GG':
|
||||
case 'GGG':
|
||||
return $this->_locale->getEraName($era,'abbreviated');
|
||||
case 'GGGG':
|
||||
return $this->_locale->getEraName($era,'wide');
|
||||
case 'GGGGG':
|
||||
return $this->_locale->getEraName($era,'narrow');
|
||||
default:
|
||||
throw new CException(Yii::t('yii','The pattern for era must be "G", "GG", "GGG", "GGGG" or "GGGGG".'));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user