В этой статье рассмотрим возможность вывода дат в динамическом формате относительно текущего момента (например: только что, 5 минут назад, позавчера, 1 июня и т.д.). Нечто похожее, кстати, можно увидеть в ВК.
Для реализации буду создавать класс Date с несколькими статическими методами, каждый из которых будет возвращать дату в определённом формате. Также для вывода месяцев и дней недели в нужном падеже подключу библиотеку Morphos. Конечно, на небольшом сайте лишь ради дат подключать целую библиотеку не стоит, резоннее будет просклонять два десятка слов вручную. Но для статьи я всё же её подключу.
Начинаем писать код с подключения библиотеки, пишем класс Date и сразу вставляем два массива с названиями месяцев и дней недели:
<?php
require 'vendor/autoload.php'; // Подключаем библ.
class Date
{
private static $months = array (
1 => 'январь', 2 => 'февраль', 3 => 'март',
4 => 'апрель', 5 => 'май', 6 => 'июнь',
7 => 'июль', 8 => 'август', 9 => 'сентябрь',
10 => 'октябрь', 11 => 'ноябрь', 12 => 'декабрь'
);
private static $weekday = array (
'воскресенье', 'понедельник', 'вторник',
'среда', 'четверг', 'пятница', 'суббота'
);
// Тут будут методы класса
}
1. Метод ago()
Первый метод ago() будет возвращать дату в формате относительно текущего времени (в зависимости от интервала):
public static function ago( $timestamp )
{
$interval = time() - $timestamp;
if ( $interval < 60 ) // Если интервал меньше 60 секунд
return 'только что';
if ( $interval < 120 ) // Если интервал меньше 2-х минут (120с)
return 'минуту назад';
if ( $interval < 3600 ) // Если интервал меньше часа
return \morphos\Russian\TimeSpeller::spellDifference( '+' . intdiv( $interval, 60 ) . ' minutes' ) . ' назад';
if ( $interval < 7200 ) // Если интервал меньше двух часов
return 'час назад';
if ( $interval < 14400 ) // Если интервал меньше четырёх часов
return floor( $interval / 3600 ) . ' часа назад';
if ( date( 'd.m.Y', $timestamp ) == date( 'd.m.Y', time() ) ) // Если это текущий день
return 'сегодня в ' . date( 'H:i', $timestamp );
if ( $timestamp >= mktime( 0, 0, 0, date( 'm' ), date( 'd' ) - 1, date( 'Y' ) ) and $timestamp < mktime( 0, 0, 0, date( 'm' ), date( 'd' ), date( 'Y' ) ) ) // Если это вчерашний день
return 'вчера в ' . date( 'H:i', $timestamp );
if ( $timestamp < mktime( 0, 0, 0, date( 'm' ), date( 'd' ) - 1, date( 'Y' ) ) and $timestamp >= mktime( 0, 0, 0, 1, 1, date( 'Y' ) ) ) // Если текущий год
return date( 'n', $timestamp ) . ' ' . \morphos\Russian\NounDeclension::getCase( self::$months[date( 'n', $timestamp )], 'родительный' );
if ( $timestamp < mktime( 0, 0, 0, date( 'm' ), date( 'd' ) - 1, date( 'Y' ) ) and $timestamp < mktime( 0, 0, 0, 1, 1, date( 'Y' ) ) ) // Если это уже прошедший год
return date( 'n', $timestamp ) . ' ' . \morphos\Russian\NounDeclension::getCase( self::$months[date( 'n', $timestamp )], 'родительный' ) . ', ' . date( 'Y', $timestamp );
return 'Не определено';
}
На вход метод получает таймштумп и возвращает строку. Также тут можно сразу заметить библиотечные методы. Всего их тут два:
2. Метод dayMonthYear()
Да, другого названия не придумал 🙁
Метод получает всё тот же таймштамп и возвращает дату в формате "число месяц, год" (пример: 4 января, 2008):
public static function dayMonthYear( $timestamp )
{
$month = \morphos\Russian\NounDeclension::getCase( self::$months[date( 'n', $timestamp )], 'родительный' ); // Склоняем месяц в Р.П.
return date( 'd', $timestamp ) . ' ' . $month . ', ' . date( 'Y', $timestamp );
}
3. Метод relatToday()
В отличие от метода ago() возвращает только число (без времени), а также день недели (если это текущий год):
public static function relatToday( $timestamp )
{
$today_start = mktime( 0, 0, 0, date( 'm' ), date( 'd' ), date( 'Y' ) ); // Начало сегодняшего дня
if ( $today_start <= $timestamp ) // Если это сегодняшний (текущий) день
return 'Сегодня';
if ( $today_start - 86400 <= $timestamp ) // Если это вчерашний день
return 'Вчера';
if ( $today_start - 86400 * 2 <= $timestamp ) // Если это позавчерашний день
return 'Позавчера';
if ( date( 'Y' ) == date( 'Y', $timestamp ) ) // Если это текущий год
return date( 'j', $timestamp ) . ' ' . \morphos\Russian\NounDeclension::getCase( self::$months[date( 'n', $timestamp )], 'родительный' ) . ', ' . self::$weekday[date( 'w', $timestamp )];
if ( date( 'Y' ) > date( 'Y', $timestamp ) ) // Если прошедний год
return date( 'j', $timestamp ) . ' ' . \morphos\Russian\NounDeclension::getCase( self::$months[date( 'n', $timestamp )], 'родительный' ) . ', ' . date( 'Y', $timestamp );
return 'Не определено';
}
Теперь можно протестить, как и что воркает:
echo Date::ago( 1657715033 ) . '<br>';
echo Date::ago( 1657711033 ) . '<br>';
echo Date::ago( 1657617829 ) . '<br>';
echo Date::ago( 1657013029 ) . '<br>';
echo Date::ago( 1625390629 ) . '<br>';
echo '<br>';
echo Date::dayMonthYear( 1573721072 ) . '<br>';
echo '<br>';
echo Date::relatToday( 1657715033 ) . '<br>';
echo Date::relatToday( 1657617957 ) . '<br>';
echo Date::relatToday( 1657531557 ) . '<br>';
echo Date::relatToday( 1657358757 ) . '<br>';
echo Date::relatToday( 1554629157 ) . '<br>';
На этом всё) Архив с файлами из статьи прикрепляю:
Перед публикацией, советую ознакомится с правилами!
Нашли ошибку?
Вы можете сообщить об этом администрации.
Выделив текст нажмите CTRL+Enter