Как стать автором
Обновить

Локализованное форматирование даты в Laravel

Время на прочтение3 мин
Количество просмотров18K
Сейчас я приведу очень простой способ того, как можно сделать в проекте локализованное форматирование даты на фреймворке Laravel. В конечном итоге мы получим результат, при котором получая свойство модели, к примеру, created_at (timestamp формат: 2015-10-20 19:45:56) — преобразуется в «20 Октября в 19:45». Форматирование можно будет настроить по вкусу или исходя из нужд.

Создание файла с переводами


Создаем date.php в директории app/lang/ru (если текущий язык русский). В его содержании будет формат вывода даты со временем и правильные окончания для месяцев.

<?php

return [
    'later'             => ':date в :time',
    'today'             => 'сегодня в :time',
    'yesterday'         => 'вчера в :time',
    'month_declensions' => [
        'January'   => 'Января',
        'February'  => 'Февраля',
        'March'     => 'Марта',
        'April'     => 'Апреля',
        'May'       => 'Мая',
        'June'      => 'Июня',
        'July'      => 'Июля',
        'August'    => 'Августа',
        'September' => 'Сентября',
        'October'   => 'Октября',
        'November'  => 'Ноября',
        'December'  => 'Декабря'
    ]
];


Для английского языка:
<?php

return [
    'later'             => ':date at :time',
    'today'             => 'today at :time',
    'yesterday'         => 'yesterday at :time',
    'month_declensions' => [
        'January'   => 'January',
        'February'  => 'February',
        'March'     => 'March',
        'April'     => 'April',
        'May'       => 'May',
        'June'      => 'June',
        'July'      => 'July',
        'August'    => 'August',
        'September' => 'September',
        'October'   => 'October',
        'November'  => 'November',
        'December'  => 'December'
    ]
];



Создание библиотеки


Теперь реализуем библиотеку, которая будет выполнять всю нашу логику для преобразования даты.
Создаем папку app/libraries (если ее нету) и файл DateFormat.php в папке Date, полный путь будет — app/libraries/Date/DateFormat.php.

<?php

namespace Date;

class DateFormat
{

    /**
     * данный метод написан на коленке (нужно переписать)
     */
    public static function post($time)
    {
        $timestamp = strtotime($time);
        $published = date('d.m.Y', $timestamp);

        if ($published === date('d.m.Y')) {
            return trans('date.today', ['time' => date('H:i', $timestamp)]);
        } elseif ($published === date('d.m.Y', strtotime('-1 day'))) {
            return trans('date.yesterday', ['time' => date('H:i', $timestamp)]);
        } else {
            $formatted = trans('date.later', [
                'time' => date('H:i', $timestamp),
                'date' => date('d F' . (date('Y', $timestamp) === date('Y') ? null : ' Y'), $timestamp)
            ]);

            return strtr($formatted, trans('date.month_declensions'));
        }
    }

}


Автозагрузка библиотек


Для того, чтобы все библиотеки были доступны для использования, добавим в composer.json автозагрузку классов с нашей директории app/libraries:

{
    "autoload": {
        "classmap": [
            "app/libraries"
        ]
    }
}


И обновим кэш composer'a:

composer dump-autoload


Базовая модель


Здесь можно поступить несколькими способами:
  • Создать абстрактную базовую модель и унаследоваться от нее;
  • Создать типаж (trait) и добавлять его использование в наши модели.

Я выбрал первый способ, так как он показался более практичным.

В созданном файле app/models/Model.php добавляем метод, который будет вызываться при получении свойства created_at.
Вызываться он будет автоматически, нам делать для этого ничего не нужно.

<?php

use Date\DateFormat;
use Illuminate\Database\Eloquent\Model as Eloquent;

abstract class Model extends Eloquent
{

    public function getCreatedAtAttribute($attr)
    {
        return DateFormat::post($attr);
    }

}


Данный код говорит сам за себя: при получении свойства модели created_at (название атрибута преобразуется в camelCase), верни значение обработанное методом post с помощью нашей библиотеки DateFormat. Также, можно создать методы для атрибутов updated_at, deleted_at и прочих.

Теперь можно проверить все на практике, ниже будет пример модели и контроллера для получения всех постов.

Модель app/models/Post.php:

<?php

class Post extends Model
{

    /**
     * @var string The table associated with the model.
     */
    protected $table = 'posts';
}


Контроллер app/controllers/PostController.php
<?php

class PostController extends Controller
{

    public function index()
    {
        return Post::all();
    }

}


Обратимся к нашему контроллеру (не забудьте прописать условия маршрутизации) и получим на выходе массив наших постов в json-формате, где свойство created_at будет отформатировано в необходимом языке и формате.

Реализовать такой функционал можно с помощью ServiceProvider, что будет еще более простым способом. Но данный способ нагляднее.

Буду рад услышать комментарии по коду. Хотелось бы узнать, какие есть best practices для решения подобных задач.
Теги:
Хабы:
Всего голосов 6: ↑5 и ↓1+4
Комментарии16

Публикации

Истории

Работа

PHP программист
113 вакансий

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн