Вопрос или проблема
Почему в приложении 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, не стесняйтесь обращаться за помощью!