From 04cdef9126d5daa17a1f2f50e49c0b8fb5e16fbd Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Tue, 7 Feb 2012 08:01:43 +0700 Subject: [PATCH] moving TimeHelper to CakeTime --- lib/Cake/Utility/CakeTime.php | 766 ++++++++++++++++++++++++++++ lib/Cake/View/Helper/TimeHelper.php | 603 ++++------------------ 2 files changed, 874 insertions(+), 495 deletions(-) create mode 100644 lib/Cake/Utility/CakeTime.php diff --git a/lib/Cake/Utility/CakeTime.php b/lib/Cake/Utility/CakeTime.php new file mode 100644 index 00000000000..c23c4c268e3 --- /dev/null +++ b/lib/Cake/Utility/CakeTime.php @@ -0,0 +1,766 @@ +__time = $time; + return preg_replace_callback('/\%(\w+)/', array($this, '_translateSpecifier'), $format); + } + +/** + * Auxiliary function to translate a matched specifier element from a regular expression into + * a windows safe and i18n aware specifier + * + * @param array $specifier match from regular expression + * @return string converted element + */ + protected function _translateSpecifier($specifier) { + switch ($specifier[1]) { + case 'a': + $abday = __dc('cake', 'abday', 5); + if (is_array($abday)) { + return $abday[date('w', $this->__time)]; + } + break; + case 'A': + $day = __dc('cake', 'day', 5); + if (is_array($day)) { + return $day[date('w', $this->__time)]; + } + break; + case 'c': + $format = __dc('cake', 'd_t_fmt', 5); + if ($format != 'd_t_fmt') { + return $this->convertSpecifiers($format, $this->__time); + } + break; + case 'C': + return sprintf("%02d", date('Y', $this->__time) / 100); + case 'D': + return '%m/%d/%y'; + case 'e': + if (DS === '/') { + return '%e'; + } + $day = date('j', $this->__time); + if ($day < 10) { + $day = ' ' . $day; + } + return $day; + case 'eS' : + return date('jS', $this->__time); + case 'b': + case 'h': + $months = __dc('cake', 'abmon', 5); + if (is_array($months)) { + return $months[date('n', $this->__time) -1]; + } + return '%b'; + case 'B': + $months = __dc('cake', 'mon', 5); + if (is_array($months)) { + return $months[date('n', $this->__time) -1]; + } + break; + case 'n': + return "\n"; + case 'p': + case 'P': + $default = array('am' => 0, 'pm' => 1); + $meridiem = $default[date('a', $this->__time)]; + $format = __dc('cake', 'am_pm', 5); + if (is_array($format)) { + $meridiem = $format[$meridiem]; + return ($specifier[1] == 'P') ? strtolower($meridiem) : strtoupper($meridiem); + } + break; + case 'r': + $complete = __dc('cake', 't_fmt_ampm', 5); + if ($complete != 't_fmt_ampm') { + return str_replace('%p', $this->_translateSpecifier(array('%p', 'p')), $complete); + } + break; + case 'R': + return date('H:i', $this->__time); + case 't': + return "\t"; + case 'T': + return '%H:%M:%S'; + case 'u': + return ($weekDay = date('w', $this->__time)) ? $weekDay : 7; + case 'x': + $format = __dc('cake', 'd_fmt', 5); + if ($format != 'd_fmt') { + return $this->convertSpecifiers($format, $this->__time); + } + break; + case 'X': + $format = __dc('cake', 't_fmt', 5); + if ($format != 't_fmt') { + return $this->convertSpecifiers($format, $this->__time); + } + break; + } + return $specifier[0]; + } + +/** + * Converts given time (in server's time zone) to user's local time, given his/her offset from GMT. + * + * @param string $serverTime UNIX timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return integer UNIX timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function convert($serverTime, $userOffset) { + $serverOffset = $this->serverOffset(); + $gmtTime = $serverTime - $serverOffset; + $userTime = $gmtTime + $userOffset * (60*60); + return $userTime; + } + +/** + * Returns server's offset from GMT in seconds. + * + * @return integer Offset + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function serverOffset() { + return date('Z', time()); + } + +/** + * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string. + * + * @param string $dateString Datetime string + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Parsed timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function fromString($dateString, $userOffset = null) { + if (empty($dateString)) { + return false; + } + if (is_integer($dateString) || is_numeric($dateString)) { + $date = intval($dateString); + } else { + $date = strtotime($dateString); + } + if ($userOffset !== null) { + return $this->convert($date, $userOffset); + } + if ($date === -1) { + return false; + } + return $date; + } + +/** + * Returns a nicely formatted date string for given Datetime string. + * + * See http://php.net/manual/en/function.strftime.php for information on formatting + * using locale strings. + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function nice($dateString = null, $userOffset = null, $format = null) { + if ($dateString != null) { + $date = $this->fromString($dateString, $userOffset); + } else { + $date = time(); + } + if (!$format) { + $format = $this->niceFormat; + } + $format = $this->convertSpecifiers($format, $date); + return $this->_strftime($format, $date); + } + +/** + * Returns a formatted descriptive date string for given datetime string. + * + * If the given date is today, the returned string could be "Today, 16:54". + * If the given date was yesterday, the returned string could be "Yesterday, 16:54". + * If $dateString's year is the current year, the returned string does not + * include mention of the year. + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Described, relative date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function niceShort($dateString = null, $userOffset = null) { + $date = $dateString ? $this->fromString($dateString, $userOffset) : time(); + + $y = $this->isThisYear($date) ? '' : ' %Y'; + + if ($this->isToday($dateString, $userOffset)) { + $ret = __d('cake', 'Today, %s', $this->_strftime("%H:%M", $date)); + } elseif ($this->wasYesterday($dateString, $userOffset)) { + $ret = __d('cake', 'Yesterday, %s', $this->_strftime("%H:%M", $date)); + } else { + $format = $this->convertSpecifiers("%b %eS{$y}, %H:%M", $date); + $ret = $this->_strftime($format, $date); + } + + return $ret; + } + +/** + * Returns a partial SQL string to search for all records between two dates. + * + * @param string $begin Datetime string or Unix timestamp + * @param string $end Datetime string or Unix timestamp + * @param string $fieldName Name of database field to compare with + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Partial SQL string. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function daysAsSql($begin, $end, $fieldName, $userOffset = null) { + $begin = $this->fromString($begin, $userOffset); + $end = $this->fromString($end, $userOffset); + $begin = date('Y-m-d', $begin) . ' 00:00:00'; + $end = date('Y-m-d', $end) . ' 23:59:59'; + + return "($fieldName >= '$begin') AND ($fieldName <= '$end')"; + } + +/** + * Returns a partial SQL string to search for all records between two times + * occurring on the same day. + * + * @param string $dateString Datetime string or Unix timestamp + * @param string $fieldName Name of database field to compare with + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Partial SQL string. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function dayAsSql($dateString, $fieldName, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + return $this->daysAsSql($dateString, $dateString, $fieldName); + } + +/** + * Returns true if given datetime string is today. + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return boolean True if datetime string is today + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public function isToday($dateString, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + return date('Y-m-d', $date) == date('Y-m-d', time()); + } + +/** + * Returns true if given datetime string is within this week. + * + * @param string $dateString + * @param integer $userOffset User's offset from GMT (in hours) + * @return boolean True if datetime string is within current week + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public function isThisWeek($dateString, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + return date('W o', $date) == date('W o', time()); + } + +/** + * Returns true if given datetime string is within this month + * @param string $dateString + * @param integer $userOffset User's offset from GMT (in hours) + * @return boolean True if datetime string is within current month + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public function isThisMonth($dateString, $userOffset = null) { + $date = $this->fromString($dateString); + return date('m Y', $date) == date('m Y', time()); + } + +/** + * Returns true if given datetime string is within current year. + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return boolean True if datetime string is within current year + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public function isThisYear($dateString, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + return date('Y', $date) == date('Y', time()); + } + +/** + * Returns true if given datetime string was yesterday. + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return boolean True if datetime string was yesterday + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + * + */ + public function wasYesterday($dateString, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday')); + } + +/** + * Returns true if given datetime string is tomorrow. + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return boolean True if datetime string was yesterday + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public function isTomorrow($dateString, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + return date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow')); + } + +/** + * Returns the quarter + * + * @param string $dateString + * @param boolean $range if true returns a range in Y-m-d format + * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function toQuarter($dateString, $range = false) { + $time = $this->fromString($dateString); + $date = ceil(date('m', $time) / 3); + + if ($range === true) { + $range = 'Y-m-d'; + } + + if ($range !== false) { + $year = date('Y', $time); + + switch ($date) { + case 1: + $date = array($year.'-01-01', $year.'-03-31'); + break; + case 2: + $date = array($year.'-04-01', $year.'-06-30'); + break; + case 3: + $date = array($year.'-07-01', $year.'-09-30'); + break; + case 4: + $date = array($year.'-10-01', $year.'-12-31'); + break; + } + } + return $date; + } + +/** + * Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime(). + * + * @param string $dateString Datetime string to be represented as a Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return integer Unix timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function toUnix($dateString, $userOffset = null) { + return $this->fromString($dateString, $userOffset); + } + +/** + * Returns a date formatted for Atom RSS feeds. + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function toAtom($dateString, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + return date('Y-m-d\TH:i:s\Z', $date); + } + +/** + * Formats date for RSS feeds + * + * @param string $dateString Datetime string or Unix timestamp + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function toRSS($dateString, $userOffset = null) { + $date = $this->fromString($dateString, $userOffset); + + if (!is_null($userOffset)) { + if ($userOffset == 0) { + $timezone = '+0000'; + } else { + $hours = (int) floor(abs($userOffset)); + $minutes = (int) (fmod(abs($userOffset), $hours) * 60); + $timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT); + } + return date('D, d M Y H:i:s', $date) . ' ' . $timezone; + } + return date("r", $date); + } + +/** + * Returns either a relative date or a formatted date depending + * on the difference between the current time and given datetime. + * $datetime should be in a strtotime - parsable format, like MySQL's datetime datatype. + * + * ### Options: + * + * - `format` => a fall back format if the relative time is longer than the duration specified by end + * - `end` => The end of relative time telling + * - `userOffset` => Users offset from GMT (in hours) + * + * Relative dates look something like this: + * 3 weeks, 4 days ago + * 15 seconds ago + * + * Default date formatting is d/m/yy e.g: on 18/2/09 + * + * The returned string includes 'ago' or 'on' and assumes you'll properly add a word + * like 'Posted ' before the function output. + * + * @param string $dateTime Datetime string or Unix timestamp + * @param array $options Default format if timestamp is used in $dateString + * @return string Relative time string. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function timeAgoInWords($dateTime, $options = array()) { + $userOffset = null; + if (is_array($options) && isset($options['userOffset'])) { + $userOffset = $options['userOffset']; + } + $now = time(); + if (!is_null($userOffset)) { + $now = $this->convert(time(), $userOffset); + } + $inSeconds = $this->fromString($dateTime, $userOffset); + $backwards = ($inSeconds > $now); + + $format = 'j/n/y'; + $end = '+1 month'; + + if (is_array($options)) { + if (isset($options['format'])) { + $format = $options['format']; + unset($options['format']); + } + if (isset($options['end'])) { + $end = $options['end']; + unset($options['end']); + } + } else { + $format = $options; + } + + if ($backwards) { + $futureTime = $inSeconds; + $pastTime = $now; + } else { + $futureTime = $now; + $pastTime = $inSeconds; + } + $diff = $futureTime - $pastTime; + + // If more than a week, then take into account the length of months + if ($diff >= 604800) { + $current = array(); + $date = array(); + + list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime)); + + list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime)); + $years = $months = $weeks = $days = $hours = $minutes = $seconds = 0; + + if ($future['Y'] == $past['Y'] && $future['m'] == $past['m']) { + $months = 0; + $years = 0; + } else { + if ($future['Y'] == $past['Y']) { + $months = $future['m'] - $past['m']; + } else { + $years = $future['Y'] - $past['Y']; + $months = $future['m'] + ((12 * $years) - $past['m']); + + if ($months >= 12) { + $years = floor($months / 12); + $months = $months - ($years * 12); + } + + if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] == 1) { + $years --; + } + } + } + + if ($future['d'] >= $past['d']) { + $days = $future['d'] - $past['d']; + } else { + $daysInPastMonth = date('t', $pastTime); + $daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y'])); + + if (!$backwards) { + $days = ($daysInPastMonth - $past['d']) + $future['d']; + } else { + $days = ($daysInFutureMonth - $past['d']) + $future['d']; + } + + if ($future['m'] != $past['m']) { + $months --; + } + } + + if ($months == 0 && $years >= 1 && $diff < ($years * 31536000)) { + $months = 11; + $years --; + } + + if ($months >= 12) { + $years = $years + 1; + $months = $months - 12; + } + + if ($days >= 7) { + $weeks = floor($days / 7); + $days = $days - ($weeks * 7); + } + } else { + $years = $months = $weeks = 0; + $days = floor($diff / 86400); + + $diff = $diff - ($days * 86400); + + $hours = floor($diff / 3600); + $diff = $diff - ($hours * 3600); + + $minutes = floor($diff / 60); + $diff = $diff - ($minutes * 60); + $seconds = $diff; + } + $relativeDate = ''; + $diff = $futureTime - $pastTime; + + if ($diff > abs($now - $this->fromString($end))) { + $relativeDate = __d('cake', 'on %s', date($format, $inSeconds)); + } else { + if ($years > 0) { + // years and months and days + $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years); + $relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : ''; + $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : ''; + $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : ''; + } elseif (abs($months) > 0) { + // months, weeks and days + $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months); + $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : ''; + $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : ''; + } elseif (abs($weeks) > 0) { + // weeks and days + $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks); + $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : ''; + } elseif (abs($days) > 0) { + // days and hours + $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days); + $relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : ''; + } elseif (abs($hours) > 0) { + // hours and minutes + $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours); + $relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : ''; + } elseif (abs($minutes) > 0) { + // minutes only + $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes); + } else { + // seconds only + $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds); + } + + if (!$backwards) { + $relativeDate = __d('cake', '%s ago', $relativeDate); + } + } + return $relativeDate; + } + +/** + * Returns true if specified datetime was within the interval specified, else false. + * + * @param mixed $timeInterval the numeric value with space then time type. + * Example of valid types: 6 hours, 2 days, 1 minute. + * @param mixed $dateString the datestring or unix timestamp to compare + * @param integer $userOffset User's offset from GMT (in hours) + * @return boolean + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public function wasWithinLast($timeInterval, $dateString, $userOffset = null) { + $tmp = str_replace(' ', '', $timeInterval); + if (is_numeric($tmp)) { + $timeInterval = $tmp . ' ' . __d('cake', 'days'); + } + + $date = $this->fromString($dateString, $userOffset); + $interval = $this->fromString('-' . $timeInterval); + + if ($date >= $interval && $date <= time()) { + return true; + } + + return false; + } + +/** + * Returns gmt as a UNIX timestamp. + * + * @param string $string UNIX timestamp or a valid strtotime() date string + * @return integer UNIX timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function gmt($string = null) { + if ($string != null) { + $string = $this->fromString($string); + } else { + $string = time(); + } + $hour = intval(date("G", $string)); + $minute = intval(date("i", $string)); + $second = intval(date("s", $string)); + $month = intval(date("n", $string)); + $day = intval(date("j", $string)); + $year = intval(date("Y", $string)); + + return gmmktime($hour, $minute, $second, $month, $day, $year); + } + +/** + * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string. + * This function also accepts a time string and a format string as first and second parameters. + * In that case this function behaves as a wrapper for TimeHelper::i18nFormat() + * + * @param string $format date format string (or a DateTime string) + * @param string $date Datetime string (or a date format string) + * @param boolean $invalid flag to ignore results of fromString == false + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function format($format, $date = null, $invalid = false, $userOffset = null) { + $time = $this->fromString($date, $userOffset); + $_time = $this->fromString($format, $userOffset); + + if (is_numeric($_time) && $time === false) { + $format = $date; + return $this->i18nFormat($_time, $format, $invalid, $userOffset); + } + if ($time === false && $invalid !== false) { + return $invalid; + } + return date($format, $time); + } + +/** + * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string. + * It take in account the default date format for the current language if a LC_TIME file is used. + * + * @param string $date Datetime string + * @param string $format strftime format string. + * @param boolean $invalid flag to ignore results of fromString == false + * @param integer $userOffset User's offset from GMT (in hours) + * @return string Formatted and translated date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function i18nFormat($date, $format = null, $invalid = false, $userOffset = null) { + $date = $this->fromString($date, $userOffset); + if ($date === false && $invalid !== false) { + return $invalid; + } + if (empty($format)) { + $format = '%x'; + } + $format = $this->convertSpecifiers($format, $date); + return $this->_strftime($format, $date); + } + +/** + * Multibyte wrapper for strftime. + * + * Handles utf8_encoding the result of strftime when necessary. + * + * @param string $format Format string. + * @param int $date Timestamp to format. + * @return string formatted string with correct encoding. + */ + protected function _strftime($format, $date) { + $format = strftime($format, $date); + $encoding = Configure::read('App.encoding'); + + if (!empty($encoding) && $encoding === 'UTF-8') { + if (function_exists('mb_check_encoding')) { + $valid = mb_check_encoding($format, $encoding); + } else { + $valid = !Multibyte::checkMultibyte($format); + } + if (!$valid) { + $format = utf8_encode($format); + } + } + return $format; + } +} diff --git a/lib/Cake/View/Helper/TimeHelper.php b/lib/Cake/View/Helper/TimeHelper.php index 95dc61dffea..d6ac402c896 100644 --- a/lib/Cake/View/Helper/TimeHelper.php +++ b/lib/Cake/View/Helper/TimeHelper.php @@ -17,6 +17,7 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::uses('CakeTime', 'Utility'); App::uses('Multibyte', 'I18n'); App::uses('AppHelper', 'View/Helper'); @@ -27,19 +28,14 @@ * * @package Cake.View.Helper * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html + * @see CakeTime */ class TimeHelper extends AppHelper { /** - * The format to use when formatting a time using `TimeHelper::nice()` - * - * The format should use the locale strings as defined in the PHP docs under - * `strftime` (http://php.net/manual/en/function.strftime.php) - * - * @var string - * @see TimeHelper::format() + * CakeTime instance */ - public $niceFormat = '%a, %b %eS %Y, %H:%M'; + protected $_CakeTime = null; /** * Constructor @@ -48,129 +44,82 @@ class TimeHelper extends AppHelper { * @param array $settings Settings array Settings array */ public function __construct(View $View, $settings = array()) { - if (isset($settings['niceFormat'])) { - $this->niceFormat = $settings['niceFormat']; - } parent::__construct($View, $settings); + $this->_CakeTime = new CakeTime($settings); } /** - * Converts a string representing the format for the function strftime and returns a - * windows safe and i18n aware format. + * Magic accessor for deprecated attributes. * - * @param string $format Format with specifiers for strftime function. - * Accepts the special specifier %S which mimics the modifier S for date() - * @param string $time UNIX timestamp - * @return string windows safe and date() function compatible format for strftime - * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + * @param string $name Name of the attribute to set. + * @param string $value Value of the attribute to set. + * @return mixed */ - public function convertSpecifiers($format, $time = null) { - if (!$time) { - $time = time(); + public function __set($name, $value) { + switch ($name) { + case 'niceFormat': + $this->_CakeTime->{$name} = $value; break; + default: + $this->{$name} = $value; break; } - $this->__time = $time; - return preg_replace_callback('/\%(\w+)/', array($this, '_translateSpecifier'), $format); } /** - * Auxiliary function to translate a matched specifier element from a regular expression into - * a windows safe and i18n aware specifier + * Magic isset check for deprecated attributes. * - * @param array $specifier match from regular expression - * @return string converted element + * @param string $name Name of the attribute to check. + * @return boolean */ - protected function _translateSpecifier($specifier) { - switch ($specifier[1]) { - case 'a': - $abday = __dc('cake', 'abday', 5); - if (is_array($abday)) { - return $abday[date('w', $this->__time)]; - } - break; - case 'A': - $day = __dc('cake', 'day', 5); - if (is_array($day)) { - return $day[date('w', $this->__time)]; - } - break; - case 'c': - $format = __dc('cake', 'd_t_fmt', 5); - if ($format != 'd_t_fmt') { - return $this->convertSpecifiers($format, $this->__time); - } - break; - case 'C': - return sprintf("%02d", date('Y', $this->__time) / 100); - case 'D': - return '%m/%d/%y'; - case 'e': - if (DS === '/') { - return '%e'; - } - $day = date('j', $this->__time); - if ($day < 10) { - $day = ' ' . $day; - } - return $day; - case 'eS' : - return date('jS', $this->__time); - case 'b': - case 'h': - $months = __dc('cake', 'abmon', 5); - if (is_array($months)) { - return $months[date('n', $this->__time) -1]; - } - return '%b'; - case 'B': - $months = __dc('cake', 'mon', 5); - if (is_array($months)) { - return $months[date('n', $this->__time) -1]; - } - break; - case 'n': - return "\n"; - case 'p': - case 'P': - $default = array('am' => 0, 'pm' => 1); - $meridiem = $default[date('a', $this->__time)]; - $format = __dc('cake', 'am_pm', 5); - if (is_array($format)) { - $meridiem = $format[$meridiem]; - return ($specifier[1] == 'P') ? strtolower($meridiem) : strtoupper($meridiem); - } - break; - case 'r': - $complete = __dc('cake', 't_fmt_ampm', 5); - if ($complete != 't_fmt_ampm') { - return str_replace('%p', $this->_translateSpecifier(array('%p', 'p')), $complete); - } - break; - case 'R': - return date('H:i', $this->__time); - case 't': - return "\t"; - case 'T': - return '%H:%M:%S'; - case 'u': - return ($weekDay = date('w', $this->__time)) ? $weekDay : 7; - case 'x': - $format = __dc('cake', 'd_fmt', 5); - if ($format != 'd_fmt') { - return $this->convertSpecifiers($format, $this->__time); - } - break; - case 'X': - $format = __dc('cake', 't_fmt', 5); - if ($format != 't_fmt') { - return $this->convertSpecifiers($format, $this->__time); - } - break; + public function __isset($name) { + if (isset($this->{$name})) { + return true; } - return $specifier[0]; + $magicGet = array('niceFormat'); + if (in_array($name, $magicGet)) { + return $this->__get($name) !== null; + } + return null; + } + +/** + * Magic accessor for attributes that were deprecated. + * + * @param string $name Name of the attribute to get. + * @return mixed + */ + public function __get($name) { + if (isset($this->_CakeTime->{$name})) { + return $this->_CakeTime->{$name}; + } + $magicGet = array('niceFormat'); + if (in_array($name, $magicGet)) { + return $this->_CakeTime->{$name}; + } + return null; + } + + /** + * Call methods from CakeTime utility class + */ + public function __call($method, $params) { + return call_user_func_array(array($this->_CakeTime, $method), $params); } /** - * Converts given time (in server's time zone) to user's local time, given his/her offset from GMT. + * @see CakeTime::convertSpecifiers() + * + * @param string $format Format with specifiers for strftime function. + * Accepts the special specifier %S which mimics the modifier S for date() + * @param string $time UNIX timestamp + * @return string windows safe and date() function compatible format for strftime + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public function convertSpecifiers($format, $time = null) { + return $this->_CakeTime->convertSpecifiers($format, $time); + } + +/** + * @see CakeTime::convert() * * @param string $serverTime UNIX timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -178,24 +127,21 @@ protected function _translateSpecifier($specifier) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function convert($serverTime, $userOffset) { - $serverOffset = $this->serverOffset(); - $gmtTime = $serverTime - $serverOffset; - $userTime = $gmtTime + $userOffset * (60*60); - return $userTime; + return $this->_CakeTime->convert($serverTime, $userOffset); } /** - * Returns server's offset from GMT in seconds. + * @see CakeTime::serverOffset() * * @return integer Offset * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function serverOffset() { - return date('Z', time()); + return $this->_CakeTime->serverOffset(); } /** - * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string. + * @see CakeTime::fromString() * * @param string $dateString Datetime string * @param integer $userOffset User's offset from GMT (in hours) @@ -203,28 +149,11 @@ public function serverOffset() { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function fromString($dateString, $userOffset = null) { - if (empty($dateString)) { - return false; - } - if (is_integer($dateString) || is_numeric($dateString)) { - $date = intval($dateString); - } else { - $date = strtotime($dateString); - } - if ($userOffset !== null) { - return $this->convert($date, $userOffset); - } - if ($date === -1) { - return false; - } - return $date; + return $this->_CakeTime->fromString($dateString, $userOffset); } /** - * Returns a nicely formatted date string for given Datetime string. - * - * See http://php.net/manual/en/function.strftime.php for information on formatting - * using locale strings. + * @see CakeTime::nice() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -233,25 +162,11 @@ public function fromString($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function nice($dateString = null, $userOffset = null, $format = null) { - if ($dateString != null) { - $date = $this->fromString($dateString, $userOffset); - } else { - $date = time(); - } - if (!$format) { - $format = $this->niceFormat; - } - $format = $this->convertSpecifiers($format, $date); - return $this->_strftime($format, $date); + return $this->_CakeTime->nice($dateString, $userOffset, $format); } /** - * Returns a formatted descriptive date string for given datetime string. - * - * If the given date is today, the returned string could be "Today, 16:54". - * If the given date was yesterday, the returned string could be "Yesterday, 16:54". - * If $dateString's year is the current year, the returned string does not - * include mention of the year. + * @see CakeTime::niceShort() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -259,24 +174,11 @@ public function nice($dateString = null, $userOffset = null, $format = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function niceShort($dateString = null, $userOffset = null) { - $date = $dateString ? $this->fromString($dateString, $userOffset) : time(); - - $y = $this->isThisYear($date) ? '' : ' %Y'; - - if ($this->isToday($dateString, $userOffset)) { - $ret = __d('cake', 'Today, %s', $this->_strftime("%H:%M", $date)); - } elseif ($this->wasYesterday($dateString, $userOffset)) { - $ret = __d('cake', 'Yesterday, %s', $this->_strftime("%H:%M", $date)); - } else { - $format = $this->convertSpecifiers("%b %eS{$y}, %H:%M", $date); - $ret = $this->_strftime($format, $date); - } - - return $ret; + return $this->_CakeTime->niceShort($dateString, $userOffset); } /** - * Returns a partial SQL string to search for all records between two dates. + * @see CakeTime::daysAsSql() * * @param string $begin Datetime string or Unix timestamp * @param string $end Datetime string or Unix timestamp @@ -286,17 +188,11 @@ public function niceShort($dateString = null, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function daysAsSql($begin, $end, $fieldName, $userOffset = null) { - $begin = $this->fromString($begin, $userOffset); - $end = $this->fromString($end, $userOffset); - $begin = date('Y-m-d', $begin) . ' 00:00:00'; - $end = date('Y-m-d', $end) . ' 23:59:59'; - - return "($fieldName >= '$begin') AND ($fieldName <= '$end')"; + return $this->_CakeTime->daysAsSql($begin, $end, $fieldName, $userOffset); } /** - * Returns a partial SQL string to search for all records between two times - * occurring on the same day. + * @see CakeTime::dayAsSql() * * @param string $dateString Datetime string or Unix timestamp * @param string $fieldName Name of database field to compare with @@ -305,12 +201,11 @@ public function daysAsSql($begin, $end, $fieldName, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function dayAsSql($dateString, $fieldName, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - return $this->daysAsSql($dateString, $dateString, $fieldName); + return $this->_CakeTime->dayAsSql($dateString, $fieldName, $userOffset); } /** - * Returns true if given datetime string is today. + * @see CakeTime::isToday() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -318,12 +213,11 @@ public function dayAsSql($dateString, $fieldName, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time */ public function isToday($dateString, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - return date('Y-m-d', $date) == date('Y-m-d', time()); + return $this->_CakeTime->isToday($dateString, $userOffset); } /** - * Returns true if given datetime string is within this week. + * @see CakeTime::isThisWeek() * * @param string $dateString * @param integer $userOffset User's offset from GMT (in hours) @@ -331,24 +225,23 @@ public function isToday($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time */ public function isThisWeek($dateString, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - return date('W o', $date) == date('W o', time()); + return $this->_CakeTime->isThisWeek($dateString, $userOffset); } /** - * Returns true if given datetime string is within this month + * @see CakeTime::isThisMonth() + * * @param string $dateString * @param integer $userOffset User's offset from GMT (in hours) * @return boolean True if datetime string is within current month * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time */ public function isThisMonth($dateString, $userOffset = null) { - $date = $this->fromString($dateString); - return date('m Y', $date) == date('m Y', time()); + return $this->_CakeTime->isThisMonth($dateString, $userOffset); } /** - * Returns true if given datetime string is within current year. + * @see CakeTime::isThisYear() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -356,12 +249,11 @@ public function isThisMonth($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time */ public function isThisYear($dateString, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - return date('Y', $date) == date('Y', time()); + return $this->_CakeTime->isThisYear($dateString, $userOffset); } /** - * Returns true if given datetime string was yesterday. + * @see CakeTime::wasYesterday() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -370,12 +262,11 @@ public function isThisYear($dateString, $userOffset = null) { * */ public function wasYesterday($dateString, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday')); + return $this->_CakeTime->wasYesterday($dateString, $userOffset); } /** - * Returns true if given datetime string is tomorrow. + * @see CakeTime::isTomorrow() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -383,12 +274,11 @@ public function wasYesterday($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time */ public function isTomorrow($dateString, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - return date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow')); + return $this->_CakeTime->isTomorrow($dateString, $userOffset); } /** - * Returns the quarter + * @see CakeTime::toQuarter() * * @param string $dateString * @param boolean $range if true returns a range in Y-m-d format @@ -396,36 +286,11 @@ public function isTomorrow($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function toQuarter($dateString, $range = false) { - $time = $this->fromString($dateString); - $date = ceil(date('m', $time) / 3); - - if ($range === true) { - $range = 'Y-m-d'; - } - - if ($range !== false) { - $year = date('Y', $time); - - switch ($date) { - case 1: - $date = array($year.'-01-01', $year.'-03-31'); - break; - case 2: - $date = array($year.'-04-01', $year.'-06-30'); - break; - case 3: - $date = array($year.'-07-01', $year.'-09-30'); - break; - case 4: - $date = array($year.'-10-01', $year.'-12-31'); - break; - } - } - return $date; + return $this->_CakeTime->toQuarter($dateString, $range); } /** - * Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime(). + * @see CakeTime::toUnix() * * @param string $dateString Datetime string to be represented as a Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -433,11 +298,11 @@ public function toQuarter($dateString, $range = false) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function toUnix($dateString, $userOffset = null) { - return $this->fromString($dateString, $userOffset); + return $this->_CakeTime->toUnix($dateString, $userOffset); } /** - * Returns a date formatted for Atom RSS feeds. + * @see CakeTime::toAtom() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -445,12 +310,11 @@ public function toUnix($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function toAtom($dateString, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - return date('Y-m-d\TH:i:s\Z', $date); + return $this->_CakeTime->toAtom($dateString, $userOffset); } /** - * Formats date for RSS feeds + * @see CakeTime::toRSS() * * @param string $dateString Datetime string or Unix timestamp * @param integer $userOffset User's offset from GMT (in hours) @@ -458,40 +322,11 @@ public function toAtom($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function toRSS($dateString, $userOffset = null) { - $date = $this->fromString($dateString, $userOffset); - - if (!is_null($userOffset)) { - if ($userOffset == 0) { - $timezone = '+0000'; - } else { - $hours = (int) floor(abs($userOffset)); - $minutes = (int) (fmod(abs($userOffset), $hours) * 60); - $timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT); - } - return date('D, d M Y H:i:s', $date) . ' ' . $timezone; - } - return date("r", $date); + return $this->_CakeTime->toRSS($dateString, $userOffset); } /** - * Returns either a relative date or a formatted date depending - * on the difference between the current time and given datetime. - * $datetime should be in a strtotime - parsable format, like MySQL's datetime datatype. - * - * ### Options: - * - * - `format` => a fall back format if the relative time is longer than the duration specified by end - * - `end` => The end of relative time telling - * - `userOffset` => Users offset from GMT (in hours) - * - * Relative dates look something like this: - * 3 weeks, 4 days ago - * 15 seconds ago - * - * Default date formatting is d/m/yy e.g: on 18/2/09 - * - * The returned string includes 'ago' or 'on' and assumes you'll properly add a word - * like 'Posted ' before the function output. + * @see CakeTime::timeAgoInWords() * * @param string $dateTime Datetime string or Unix timestamp * @param array $options Default format if timestamp is used in $dateString @@ -499,163 +334,11 @@ public function toRSS($dateString, $userOffset = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function timeAgoInWords($dateTime, $options = array()) { - $userOffset = null; - if (is_array($options) && isset($options['userOffset'])) { - $userOffset = $options['userOffset']; - } - $now = time(); - if (!is_null($userOffset)) { - $now = $this->convert(time(), $userOffset); - } - $inSeconds = $this->fromString($dateTime, $userOffset); - $backwards = ($inSeconds > $now); - - $format = 'j/n/y'; - $end = '+1 month'; - - if (is_array($options)) { - if (isset($options['format'])) { - $format = $options['format']; - unset($options['format']); - } - if (isset($options['end'])) { - $end = $options['end']; - unset($options['end']); - } - } else { - $format = $options; - } - - if ($backwards) { - $futureTime = $inSeconds; - $pastTime = $now; - } else { - $futureTime = $now; - $pastTime = $inSeconds; - } - $diff = $futureTime - $pastTime; - - // If more than a week, then take into account the length of months - if ($diff >= 604800) { - $current = array(); - $date = array(); - - list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime)); - - list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime)); - $years = $months = $weeks = $days = $hours = $minutes = $seconds = 0; - - if ($future['Y'] == $past['Y'] && $future['m'] == $past['m']) { - $months = 0; - $years = 0; - } else { - if ($future['Y'] == $past['Y']) { - $months = $future['m'] - $past['m']; - } else { - $years = $future['Y'] - $past['Y']; - $months = $future['m'] + ((12 * $years) - $past['m']); - - if ($months >= 12) { - $years = floor($months / 12); - $months = $months - ($years * 12); - } - - if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] == 1) { - $years --; - } - } - } - - if ($future['d'] >= $past['d']) { - $days = $future['d'] - $past['d']; - } else { - $daysInPastMonth = date('t', $pastTime); - $daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y'])); - - if (!$backwards) { - $days = ($daysInPastMonth - $past['d']) + $future['d']; - } else { - $days = ($daysInFutureMonth - $past['d']) + $future['d']; - } - - if ($future['m'] != $past['m']) { - $months --; - } - } - - if ($months == 0 && $years >= 1 && $diff < ($years * 31536000)) { - $months = 11; - $years --; - } - - if ($months >= 12) { - $years = $years + 1; - $months = $months - 12; - } - - if ($days >= 7) { - $weeks = floor($days / 7); - $days = $days - ($weeks * 7); - } - } else { - $years = $months = $weeks = 0; - $days = floor($diff / 86400); - - $diff = $diff - ($days * 86400); - - $hours = floor($diff / 3600); - $diff = $diff - ($hours * 3600); - - $minutes = floor($diff / 60); - $diff = $diff - ($minutes * 60); - $seconds = $diff; - } - $relativeDate = ''; - $diff = $futureTime - $pastTime; - - if ($diff > abs($now - $this->fromString($end))) { - $relativeDate = __d('cake', 'on %s', date($format, $inSeconds)); - } else { - if ($years > 0) { - // years and months and days - $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years); - $relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : ''; - $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : ''; - $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : ''; - } elseif (abs($months) > 0) { - // months, weeks and days - $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months); - $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : ''; - $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : ''; - } elseif (abs($weeks) > 0) { - // weeks and days - $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks); - $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : ''; - } elseif (abs($days) > 0) { - // days and hours - $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days); - $relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : ''; - } elseif (abs($hours) > 0) { - // hours and minutes - $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours); - $relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : ''; - } elseif (abs($minutes) > 0) { - // minutes only - $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes); - } else { - // seconds only - $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds); - } - - if (!$backwards) { - $relativeDate = __d('cake', '%s ago', $relativeDate); - } - } - return $relativeDate; + return $this->_CakeTime->timeAgoInWords($dateTime, $options); } /** - * Returns true if specified datetime was within the interval specified, else false. + * @see CakeTime::wasWithinLast() * * @param mixed $timeInterval the numeric value with space then time type. * Example of valid types: 6 hours, 2 days, 1 minute. @@ -665,48 +348,22 @@ public function timeAgoInWords($dateTime, $options = array()) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time */ public function wasWithinLast($timeInterval, $dateString, $userOffset = null) { - $tmp = str_replace(' ', '', $timeInterval); - if (is_numeric($tmp)) { - $timeInterval = $tmp . ' ' . __d('cake', 'days'); - } - - $date = $this->fromString($dateString, $userOffset); - $interval = $this->fromString('-' . $timeInterval); - - if ($date >= $interval && $date <= time()) { - return true; - } - - return false; + return $this->_CakeTime->wasWithinLast($timeInterval, $dateString, $userOffset); } /** - * Returns gmt as a UNIX timestamp. + * @see CakeTime::gmt() * * @param string $string UNIX timestamp or a valid strtotime() date string * @return integer UNIX timestamp * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function gmt($string = null) { - if ($string != null) { - $string = $this->fromString($string); - } else { - $string = time(); - } - $hour = intval(date("G", $string)); - $minute = intval(date("i", $string)); - $second = intval(date("s", $string)); - $month = intval(date("n", $string)); - $day = intval(date("j", $string)); - $year = intval(date("Y", $string)); - - return gmmktime($hour, $minute, $second, $month, $day, $year); + return $this->_CakeTime->gmt($string); } /** - * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string. - * This function also accepts a time string and a format string as first and second parameters. - * In that case this function behaves as a wrapper for TimeHelper::i18nFormat() + * @see CakeTime::format() * * @param string $format date format string (or a DateTime string) * @param string $date Datetime string (or a date format string) @@ -716,22 +373,11 @@ public function gmt($string = null) { * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function format($format, $date = null, $invalid = false, $userOffset = null) { - $time = $this->fromString($date, $userOffset); - $_time = $this->fromString($format, $userOffset); - - if (is_numeric($_time) && $time === false) { - $format = $date; - return $this->i18nFormat($_time, $format, $invalid, $userOffset); - } - if ($time === false && $invalid !== false) { - return $invalid; - } - return date($format, $time); + return $this->_CakeTime->format($format, $date, $invalid, $userOffset); } /** - * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string. - * It take in account the default date format for the current language if a LC_TIME file is used. + * @see CakeTime::i18nFormat() * * @param string $date Datetime string * @param string $format strftime format string. @@ -741,40 +387,7 @@ public function format($format, $date = null, $invalid = false, $userOffset = nu * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */ public function i18nFormat($date, $format = null, $invalid = false, $userOffset = null) { - $date = $this->fromString($date, $userOffset); - if ($date === false && $invalid !== false) { - return $invalid; - } - if (empty($format)) { - $format = '%x'; - } - $format = $this->convertSpecifiers($format, $date); - return $this->_strftime($format, $date); + return $this->_CakeTime->i18nFormat($date, $format, $invalid, $userOffset); } -/** - * Multibyte wrapper for strftime. - * - * Handles utf8_encoding the result of strftime when necessary. - * - * @param string $format Format string. - * @param int $date Timestamp to format. - * @return string formatted string with correct encoding. - */ - protected function _strftime($format, $date) { - $format = strftime($format, $date); - $encoding = Configure::read('App.encoding'); - - if (!empty($encoding) && $encoding === 'UTF-8') { - if (function_exists('mb_check_encoding')) { - $valid = mb_check_encoding($format, $encoding); - } else { - $valid = !Multibyte::checkMultibyte($format); - } - if (!$valid) { - $format = utf8_encode($format); - } - } - return $format; - } }