Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** TSimpleDateFormatter class file** @author Wei Zhuo <weizhuo[at]gmail[dot]com>* @link http://www.pradosoft.com/* @copyright Copyright © 2005-2008 PradoSoft* @license http://www.pradosoft.com/license/* @version $Id: TSimpleDateFormatter.php 2488 2008-08-06 01:34:06Z knut $* @package System.Util*//*** TSimpleDateFormatter class.** Formats and parses dates using the SimpleDateFormat pattern.* This pattern is compatible with the I18N and java's SimpleDateFormatter.* <code>* Pattern | Description* ----------------------------------------------------* d | Day of month 1 to 31, no padding* dd | Day of monath 01 to 31, zero leading* M | Month digit 1 to 12, no padding* MM | Month digit 01 to 12, zero leading* yy | 2 year digit, e.g., 96, 05* yyyy | 4 year digit, e.g., 2005* ----------------------------------------------------* </code>** Usage example, to format a date* <code>* $formatter = new TSimpleDateFormatter("dd/MM/yyy");* echo $formatter->format(time());* </code>** To parse the date string into a date timestamp.* <code>* $formatter = new TSimpleDateFormatter("d-M-yyy");* echo $formatter->parse("24-6-2005");* </code>** @author Wei Zhuo <weizhuo[at]gmail[dot]com>* @version $Id: TSimpleDateFormatter.php 2488 2008-08-06 01:34:06Z knut $* @package System.Util* @since 3.0*/class TSimpleDateFormatter{/*** Formatting pattern.* @var string*/private $pattern;/*** Charset, default is 'UTF-8'* @var string*/private $charset = 'UTF-8';/*** Constructor, create a new date time formatter.* @param string formatting pattern.* @param string pattern and value charset*/public function __construct($pattern, $charset='UTF-8'){$this->setPattern($pattern);$this->setCharset($charset);}/*** @return string formatting pattern.*/public function getPattern(){return $this->pattern;}/*** @param string formatting pattern.*/public function setPattern($pattern){$this->pattern = $pattern;}/*** @return string formatting charset.*/public function getCharset(){return $this->charset;}/*** @param string formatting charset.*/public function setCharset($charset){$this->charset = $charset;}/*** Format the date according to the pattern.* @param string|int the date to format, either integer or a string readable by strtotime.* @return string formatted date.*/public function format($value){$date = $this->getDate($value);$bits['yyyy'] = $date['year'];$bits['yy'] = substr("{$date['year']}", -2);$bits['MM'] = str_pad("{$date['mon']}", 2, '0', STR_PAD_LEFT);$bits['M'] = $date['mon'];$bits['dd'] = str_pad("{$date['mday']}", 2, '0', STR_PAD_LEFT);$bits['d'] = $date['mday'];$pattern = preg_replace('/M{3,4}/', 'MM', $this->pattern);return str_replace(array_keys($bits), $bits, $pattern);}public function getMonthPattern(){if(is_int(strpos($this->pattern, 'MMMM')))return 'MMMM';if(is_int(strpos($this->pattern, 'MMM')))return 'MMM';if(is_int(strpos($this->pattern, 'MM')))return 'MM';if(is_int(strpos($this->pattern, 'M')))return 'M';return false;}public function getDayPattern(){if(is_int(strpos($this->pattern, 'dd')))return 'dd';if(is_int(strpos($this->pattern, 'd')))return 'd';return false;}public function getYearPattern(){if(is_int(strpos($this->pattern, 'yyyy')))return 'yyyy';if(is_int(strpos($this->pattern, 'yy')))return 'yy';return false;}public function getDayMonthYearOrdering(){$ordering = array();if(is_int($day= strpos($this->pattern, 'd')))$ordering['day'] = $day;if(is_int($month= strpos($this->pattern, 'M')))$ordering['month'] = $month;if(is_int($year= strpos($this->pattern, 'yy')))$ordering['year'] = $year;asort($ordering);return array_keys($ordering);}/*** Gets the time stamp from string or integer.* @param string|int date to parse* @return array date info array*/private function getDate($value){if(!is_string($value)){$s = Prado::createComponent('System.Util.TDateTimeStamp');return $s->getDate($value);}$date = @strtotime($value);if($date < 0)throw new TInvalidDataValueException('invalid_date', $value);return @getdate($date);}/*** @return boolean true if the given value matches with the date pattern.*/public function isValidDate($value){if($value === null) {return false;} else {return $this->parse($value, false) !== null;}}/*** Parse the string according to the pattern.* @param string|int date string or integer to parse* @return int date time stamp* @throws TInvalidDataValueException if date string is malformed.*/public function parse($value,$defaultToCurrentTime=true){if(is_int($value) || is_float($value))return $value;else if(!is_string($value))throw new TInvalidDataValueException('date_to_parse_must_be_string', $value);if(empty($this->pattern)) return time();$date = time();if($this->length(trim($value)) < 1)return $defaultToCurrentTime ? $date : null;$pattern = $this->pattern;$i_val = 0;$i_format = 0;$pattern_length = $this->length($pattern);$c = '';$token='';$x=null; $y=null;if($defaultToCurrentTime){$year = "{$date['year']}";$month = $date['mon'];$day = $date['mday'];}else{$year = null;$month = null;$day = null;}while ($i_format < $pattern_length){$c = $this->charAt($pattern,$i_format);$token='';while ($this->charEqual($pattern, $i_format, $c)&& ($i_format < $pattern_length)){$token .= $this->charAt($pattern, $i_format++);}if ($token=='yyyy' || $token=='yy' || $token=='y'){if ($token=='yyyy') { $x=4;$y=4; }if ($token=='yy') { $x=2;$y=2; }if ($token=='y') { $x=2;$y=4; }$year = $this->getInteger($value,$i_val,$x,$y);if($year === null)return null;//throw new TInvalidDataValueException('Invalid year', $value);$i_val += strlen($year);if(strlen($year) == 2){$iYear = (int)$year;if($iYear > 70)$year = $iYear + 1900;else$year = $iYear + 2000;}$year = (int)$year;}elseif($token=='MM' || $token=='M'){$month=$this->getInteger($value,$i_val,$this->length($token),2);$iMonth = (int)$month;if($month === null || $iMonth < 1 || $iMonth > 12 )return null;//throw new TInvalidDataValueException('Invalid month', $value);$i_val += strlen($month);$month = $iMonth;}elseif ($token=='dd' || $token=='d'){$day = $this->getInteger($value,$i_val,$this->length($token), 2);$iDay = (int)$day;if($day === null || $iDay < 1 || $iDay >31)return null;//throw new TInvalidDataValueException('Invalid day', $value);$i_val += strlen($day);$day = $iDay;}else{if($this->substring($value, $i_val, $this->length($token)) != $token)return null;//throw new TInvalidDataValueException("Subpattern '{$this->pattern}' mismatch", $value);else$i_val += $this->length($token);}}if ($i_val != $this->length($value))throw new TInvalidDataValueException("Pattern '{$this->pattern}' mismatch", $value);if(!$defaultToCurrentTime && ($month === null || $day === null || $year === null))return null;else{if(empty($year)) {$year = date('Y');}$day = (int)$day <= 0 ? 1 : (int)$day;$month = (int)$month <= 0 ? 1 : (int)$month;$s = Prado::createComponent('System.Util.TDateTimeStamp');return $s->getTimeStamp(0, 0, 0, $month, $day, $year);}}/*** Calculate the length of a string, may be consider iconv_strlen?*/private function length($string){//use iconv_strlen or just strlen?return strlen($string);}/*** Get the char at a position.*/private function charAt($string, $pos){return $this->substring($string, $pos, 1);}/*** Gets a portion of a string, uses iconv_substr.*/private function substring($string, $start, $length){return iconv_substr($string, $start, $length);}/*** Returns true if char at position equals a particular char.*/private function charEqual($string, $pos, $char){return $this->charAt($string, $pos) == $char;}/*** Gets integer from part of a string, allows integers of any length.* @param string string to retrieve the integer from.* @param int starting position* @param int minimum integer length* @param int maximum integer length* @return string integer portion of the string, null otherwise*/private function getInteger($str,$i,$minlength,$maxlength){//match for digits backwardsfor ($x = $maxlength; $x >= $minlength; $x--){$token= $this->substring($str, $i,$x);if ($this->length($token) < $minlength)return null;if (preg_match('/^\d+$/', $token))return $token;}return null;}}?>