Created
January 24, 2017 13:49
-
-
Save Aleksandr-ru/49c3eccfd7e559276f19b93dfc29320d to your computer and use it in GitHub Desktop.
Русскоязычный DateTime с дополнениями
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Русскоязычный DateTime с дополнениями | |
* | |
* @author Aleksandr <[email protected]> | |
* @link http://www.aleksandr.ru author's website | |
*/ | |
class DateTimeRu extends DateTime | |
{ | |
protected static $FN = array(1=>"Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"); | |
protected static $F = array(1=>"Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Сентября", "Октября", "Ноября", "Декабря"); | |
protected static $M = array(1=>"Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"); | |
protected static $l = array("Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"); | |
protected static $D = array("Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"); | |
protected static $timeStrFormat = array( | |
// будущее | |
0 => array( | |
'y' => array('Более чем через год', 'Более чем через год', 'Более чем через год'), | |
'm' => array('Через месяц', 'Через %m месяца', 'Через %m месяцев'), | |
'd' => array('Завтра', 'Через %d дня', 'Через %d дней'), | |
'h' => array('Через час', 'Через %h часа', 'Через %h часов'), | |
'i' => array('Через минуту', 'Через %i минуты', 'Через %i минут'), | |
's' => array('Через секунду', 'Через %s секунды', 'Через %s секунд'), | |
), | |
// прошлое | |
1 => array( | |
'y' => array('Более года назад', 'Более года назад', 'Более года назад'), | |
'm' => array('Месяц назад', '%m месяца назад', '%m месяцев назад'), | |
'd' => array('Вчера', '%d дня назад', '%d дней назад'), | |
'h' => array('Час назад', '%h часа назад', '%h часов назад'), | |
'i' => array('Минуту назад', '%h минуты назад', '%h минут назад'), | |
's' => array('Секунду назад', '%s секунды назад', '%s секунд назад'), | |
), | |
// сейчас | |
'now' => 'Сейчас' | |
); | |
/** | |
* Форматировать дату/время | |
* @param string $format | |
* @param bool $nominativeMonth месяц в именительном падеже | |
* @return string | |
*/ | |
function format($format, $nominativeMonth = FALSE) | |
{ | |
$t = $this->getTimestamp(); | |
$n = date('n', $t); // Порядковый номер месяца без ведущего нуля от 1 до 12 | |
$w = date('w', $t); // Порядковый номер дня недели от 0 (воскресенье) до 6 (суббота) | |
$format = str_replace('F', $nominativeMonth ? static::$FN[$n] : static::$F[$n], $format); | |
$format = str_replace('M', static::$M[$n], $format); | |
$format = str_replace('l', static::$l[$w], $format); | |
$format = str_replace('D', static::$D[$w], $format); | |
return parent::format($format); | |
} | |
/** | |
* Получить красивую строку раницы во времени от текущего | |
* @param int $skipSeconds количество секунд, менее которого приравнивается к 'сейчас' | |
* @return string например '15 минут назад' | |
*/ | |
function getTimeDiffStr($skipSeconds = 60) | |
{ | |
$dt = new DateTime(); | |
$diff = $dt->diff($this); | |
// $diff->invert | |
// Принимает 1, если интервал представляет отрицательный период времени и 0 в противном случае. | |
if(static::DateIntervalToSeconds($diff) > $skipSeconds) { | |
if($diff->y) return $diff->format(static::morphEnding($diff->y, static::$timeStrFormat[$diff->invert]['y'])); | |
if($diff->m) return $diff->format(static::morphEnding($diff->m, static::$timeStrFormat[$diff->invert]['m'])); | |
if($diff->d) return $diff->format(static::morphEnding($diff->d, static::$timeStrFormat[$diff->invert]['d'])); | |
if($diff->h) return $diff->format(static::morphEnding($diff->h, static::$timeStrFormat[$diff->invert]['h'])); | |
if($diff->i) return $diff->format(static::morphEnding($diff->i, static::$timeStrFormat[$diff->invert]['i'])); | |
if($diff->s) return $diff->format(static::morphEnding($diff->s, static::$timeStrFormat[$diff->invert]['s'])); | |
} | |
return $diff->format(static::$timeStrFormat['now']); | |
} | |
/** | |
* морфологическое окончание | |
* @param int $n количество | |
* @param array $titles = ['1 яблоко', '2 яблока', '5 яблок'] | |
* @return string | |
*/ | |
static function morphEnding($n, $titles) | |
{ | |
$cases = array(2, 0, 1, 1, 1, 2); | |
return $titles[($n % 100 > 4 && $n % 100 < 20) ? 2 : $cases[min($n % 10, 5)]]; | |
} | |
/** | |
* Keep in mind that a year is seen in this class as 365 days, and a month is seen as 30 days. | |
* It is not possible to calculate how many days are in a given year or month without a point of reference in time. | |
* @see http://php.net/manual/ru/dateinterval.format.php#102271 | |
* @param DateInterval $di | |
* @return int | |
*/ | |
static function DateIntervalToSeconds($di) | |
{ | |
return ($di->y * 365 * 24 * 60 * 60) + | |
($di->m * 30 * 24 * 60 * 60) + | |
($di->d * 24 * 60 * 60) + | |
($di->h * 60 * 60) + | |
($di->i * 60) + | |
($di->s); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment