Почему форматированная дата с Carbon недействительна?

Вопрос или проблема

Почему в приложении Laravel 11 / PHP 8.2 выполняется следующий код

$minDay = CurrencyHistory::select(DB::raw('MIN(day) as min_day'))->first()->min_day;
\Log::info($minDay);
\Log::info(Carbon::createFromTimestamp(strtotime($minDay))->format('j F, Y'));

Я вижу результаты :

[2024-10-05 07:30:08] local.INFO: 2024-09-28
[2024-10-05 07:30:08] local.INFO: 27 сентября, 2024

Так что минимальный день 2024-09-28, но полученное значение в форме у меня 27 сентября, 2024

В модели CurrencyHistory у меня есть :

protected $casts = [
        'created_at' => 'datetime', 'updated_at' => 'datetime', 'value' => HistoryMoney::class, 'day' => 'date'
    ];

Отслеживая SQL, у меня есть :

   SELECT MIN(day)     AS min_day
    FROM `currency_histories` limit 1

Что действительно возвращает значение 2024-09-28.

Является ли формат ‘j F, Y’ недействительным? При использовании формата format('d F, Y' тот же результат…
Какой формат мне следует использовать?

Ответ или решение

Проблема, с которой вы столкнулись, заключается в том, что значение переменной $minDay в вашем коде имеет тип строки (string) и представлено в формате даты YYYY-MM-DD (например, 2024-09-28). При этом вы пытаетесь использовать функцию strtotime() для преобразования этой строки в метку времени (timestamp), а затем создаете объект Carbon на основе полученной метки времени.

Давайте разберем шаги и причины, по которым это приводит к некорректному результату.

Проблема 1: Использование strtotime()

Функция strtotime() может неправильно интерпретировать строки, особенно если они представлены в формате, отличном от ожидаемого. В вашем случае, с strtotime($minDay), функция может не правильно обрабатывать строку ‘2024-09-28’ из-за возможных настроек локали или просто из-за особенностей работы.

Проблема 2: Создание объекта Carbon

Метод Carbon::createFromTimestamp() ожидает метку времени (timestamp), а не строку даты. Однако, если strtotime() возвращает истинное значение, то вы всё равно можете использовать Carbon для создания объекта. Но если strtotime() возвращает false, вы получите неожиданный результат.

Решение

Рекомендуется использовать непосредственно созданные экземпляры Carbon без преобразования через strtotime(). Вы можете сделать это следующим образом:

$minDay = CurrencyHistory::select(DB::raw('MIN(day) as min_day'))->first()->min_day;
\Log::info($minDay);

// Создаем объект Carbon напрямую из строки даты
$date = Carbon::parse($minDay);
\Log::info($date->format('j F, Y'));

Проверка результата

Теперь, когда вы создали объект Carbon напрямую из строки $minDay, вы должны получить правильный формат даты. Для заданного значения 2024-09-28 результат будет 28 September, 2024.

Итог

Для исправления вашей проблемы используйте Carbon::parse() для создания объекта Carbon из строки с датой. Таким образом, вы получите корректное значение, соответствующее формату, который вы определяете в методе format(). Это позволят устранить ошибки форматирования и обеспечить правильное отображение даты.

Если у вас возникнут дополнительные вопросы или потребуетсяClarifications, не стесняйтесь обращаться за помощью!

Оцените материал
Добавить комментарий

Капча загружается...