From 6f7d095e3f4b09847c5963646b2f4a817d68ba39 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Sun, 18 Apr 2010 22:11:04 +0100 Subject: [PATCH] [feature/new-tz-handling] Wrapper around DateTime for new date time handling. Wrapped PHP's DateTime with some extensions for supporting phpBB's relative date formats and provided the DateTime::getTimestamp() method to PHP < 5.3. PHPBB3-9558 --- phpBB/includes/datetime.php | 160 ++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 phpBB/includes/datetime.php diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php new file mode 100644 index 0000000000..b1e95e58a3 --- /dev/null +++ b/phpBB/includes/datetime.php @@ -0,0 +1,160 @@ +_user = $user ? $user : $GLOBALS['user']; + + $timezone = (!$timezone && $this->_user->tz instanceof DateTimeZone) ? $this->_user->tz : $timezone; + + parent::__construct($time, $timezone); + } + + /** + * Returns a UNIX timestamp representation of the date time. + * + * @return int UNIX timestamp + */ + public function getTimestamp() + { + static $compat; + + if (!isset($compat)) + { + $compat = !method_exists('DateTime', 'getTimestamp'); + } + + return !$compat ? parent::getTimestamp() : (int) parent::format('U'); + } + + /** + * Formats the current date time into the specified format + * + * @param string $format Optional format to use for output, defaults to users chosen format + * @param boolean $force_absolute Force output of a non relative date + * @return string Formatted date time + */ + public function format($format = '', $force_absolute = false) + { + $format = $format ? $format : $this->_user->date_format; + $relative = (strpos($format, self::RELATIVE_WRAPPER) !== false && !$force_absolute); + $now = new self('now', $this->_user->tz, $this->_user); + $delta = $now->getTimestamp() - $this->getTimestamp(); + + if ($relative) + { + if ($delta <= 3600 && ($delta >= -5 || (($now->getTimestamp() / 60) % 60) == (($this->getTimestamp() / 60) % 60)) && isset($this->_user->lang['datetime']['AGO'])) + { + return $this->_user->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60))); + } + else + { + $midnight = clone $now; + $midnight->setTime(0, 0, 0); + + $midnight = $midnight->getTimestamp(); + $gmepoch = $this->getTimestamp(); + + if (!($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800)) + { + $day = false; + + if ($gmepoch > $midnight + 86400) + { + $day = 'TOMORROW'; + } + else if ($gmepoch > $midnight) + { + $day = 'TODAY'; + } + else if ($gmepoch > $midnight - 86400) + { + $day = 'YESTERDAY'; + } + + if ($day !== false) + { + $format = self::_format_cache($format, $this->_user); + + return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->_user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang'])); + } + } + } + } + + $format = self::_format_cache($format, $this->_user); + + return strtr(parent::format($format['format_long']), $format['lang']); + } + + /** + * Pre-processes the specified date format + * + * @param string $format Output format + * @param user $user User object to use for localisation + * @return array Processed date format + */ + static protected function _format_cache($format, $user) + { + $lang = $user->lang_name; + + if (!isset(self::$format_cache[$lang])) + { + self::$format_cache[$lang] = array(); + + if (!isset(self::$format_cache[$lang][$format])) + { + // Is the user requesting a friendly date format (i.e. 'Today 12:42')? + self::$format_cache[$lang][$format] = array( + 'is_short' => strpos($format, self::RELATIVE_WRAPPER) !== false, + 'format_short' => substr($format, 0, strpos($format, self::RELATIVE_WRAPPER)) . self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER . substr(strrchr($format, self::RELATIVE_WRAPPER), 1), + 'format_long' => str_replace(self::RELATIVE_WRAPPER, '', $format), + 'lang' => $user->lang['datetime'], + ); + + // Short representation of month in format? Some languages use different terms for the long and short format of May + if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false)) + { + self::$format_cache[$lang][$format]['lang']['May'] = $user->lang['datetime']['May_short']; + } + } + } + + return self::$format_cache[$lang][$format]; + } +}