mirror of
https://github.com/YunoHost-Apps/phpbb_ynh.git
synced 2024-09-03 19:56:36 +02:00
169 lines
5 KiB
PHP
169 lines
5 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
*
|
||
|
* This file is part of the phpBB Forum Software package.
|
||
|
*
|
||
|
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||
|
* @license GNU General Public License, version 2 (GPL-2.0)
|
||
|
*
|
||
|
* For full copyright and license information, please see
|
||
|
* the docs/CREDITS.txt file.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
namespace phpbb;
|
||
|
|
||
|
/**
|
||
|
* phpBB custom extensions to the PHP DateTime class
|
||
|
* This handles the relative formats phpBB employs
|
||
|
*/
|
||
|
class datetime extends \DateTime
|
||
|
{
|
||
|
/**
|
||
|
* String used to wrap the date segment which should be replaced by today/tomorrow/yesterday
|
||
|
*/
|
||
|
const RELATIVE_WRAPPER = '|';
|
||
|
|
||
|
/**
|
||
|
* @var user User who is the context for this DateTime instance
|
||
|
*/
|
||
|
protected $user;
|
||
|
|
||
|
/**
|
||
|
* @var array Date formats are preprocessed by phpBB, to save constant recalculation they are cached.
|
||
|
*/
|
||
|
static protected $format_cache = array();
|
||
|
|
||
|
/**
|
||
|
* Constructs a new instance of \phpbb\datetime, expanded to include an argument to inject
|
||
|
* the user context and modify the timezone to the users selected timezone if one is not set.
|
||
|
*
|
||
|
* @param user $user object for context.
|
||
|
* @param string $time String in a format accepted by strtotime().
|
||
|
* @param \DateTimeZone $timezone Time zone of the time.
|
||
|
*/
|
||
|
public function __construct($user, $time = 'now', \DateTimeZone $timezone = null)
|
||
|
{
|
||
|
$this->user = $user;
|
||
|
$timezone = $timezone ?: $this->user->timezone;
|
||
|
|
||
|
parent::__construct($time, $timezone);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
$format = self::format_cache($format, $this->user);
|
||
|
$relative = ($format['is_short'] && !$force_absolute);
|
||
|
$now = new self($this->user, 'now', $this->user->timezone);
|
||
|
|
||
|
$timestamp = $this->getTimestamp();
|
||
|
$now_ts = $now->getTimeStamp();
|
||
|
|
||
|
$delta = $now_ts - $timestamp;
|
||
|
|
||
|
if ($relative)
|
||
|
{
|
||
|
/*
|
||
|
* Check the delta is less than or equal to 1 hour
|
||
|
* and the delta not more than a minute in the past
|
||
|
* and the delta is either greater than -5 seconds or timestamp
|
||
|
* and current time are of the same minute (they must be in the same hour already)
|
||
|
* finally check that relative dates are supported by the language pack
|
||
|
*/
|
||
|
if ($delta <= 3600 && $delta > -60 &&
|
||
|
($delta >= -5 || (($now_ts / 60) % 60) == (($timestamp / 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();
|
||
|
|
||
|
if ($timestamp <= $midnight + 2 * 86400)
|
||
|
{
|
||
|
$day = false;
|
||
|
|
||
|
if ($timestamp > $midnight + 86400)
|
||
|
{
|
||
|
$day = 'TOMORROW';
|
||
|
}
|
||
|
else if ($timestamp > $midnight)
|
||
|
{
|
||
|
$day = 'TODAY';
|
||
|
}
|
||
|
else if ($timestamp > $midnight - 86400)
|
||
|
{
|
||
|
$day = 'YESTERDAY';
|
||
|
}
|
||
|
|
||
|
if ($day !== false)
|
||
|
{
|
||
|
// Format using the short formatting and finally swap out the relative token placeholder with the correct value
|
||
|
return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang']));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return strtr(parent::format($format['format_long']), $format['lang']);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Magic method to convert DateTime object to string
|
||
|
*
|
||
|
* @return string Formatted date time, according to the users default settings.
|
||
|
*/
|
||
|
public function __toString()
|
||
|
{
|
||
|
return $this->format();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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' => array_filter($user->lang['datetime'], 'is_string'),
|
||
|
);
|
||
|
|
||
|
// 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];
|
||
|
}
|
||
|
}
|