@Qu1eeeOJ

Как правильно хранить дату в БД Laravel?

Здравствуйте, столкнулся с проблемой, что дата сохраняется корректная, то есть Carbon правильно распознаёт дату. Но стоит на клиенте привести в строчку, то время различается.

Пример:
Хочу сохранить дату: 24.08.2022 09:00:00
Laravel при сохранении конвертирует дату в ISO формат и получается: 2022-08-24T09:00:00.000000Z
Но если прогнать эту дату на клиенте JS: new Date("2022-08-24T09:00:00.000000Z"), то получается: Wed Aug 24 2022 12:00:00 GMT+0300 (Москва, стандартное время).

В модели у меня стоит каст на преобразование в datetime
/**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'cancelled' => 'boolean',
        'start_at' => 'datetime',
        'end_at' => 'datetime'
    ];


Миграция:
Schema::create('table', function (Blueprint $table) {
            $table->id();
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('room_id');
            $table->string('text')->nullable();
            $table->boolean('cancelled')->default(false);
            $table->timestamp('start_at')->nullable();
            $table->timestamp('end_at')->nullable();
            $table->timestamps();
        });


Данные возвращаю из контроллера таким образом:
return response()->json(Model::query()->where('user_id', Auth::id())
            ->orderBy('id', 'asc')
            ->get()
            ->toArray());


В чём может быть проблема?
  • Вопрос задан
  • 866 просмотров
Решения вопроса 1
delphinpro
@delphinpro Куратор тега PHP
frontend developer
Вы храните дату в нулевом часовом поясе (Z в конце)
Javascript приводит дату в ваше локальное время. То есть московское, плюс три часа от исходной даты. Всё правильно.

UPD
Уточню, что в timestamp все же хранится метка времени, простой int. Но извлекается из базы это значение уже с учетом часового пояса системы, на которой установлена БД, часового пояса заданного в настройках БД (SET time_zone) или для текущей сессии (set @@session.time_zone).
Ну и php может поколдовать с поясами. У вас по-видимому в настройках указан нулевая таймзона, вот и время извлекается в ней.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
pLavrenov
@pLavrenov
Разработка сайтов
Я придерживаюсь правил:
1) Хранить в UTC
2) Передача данных Api и все что входит и выходит из компонента React(например) - ISO (2013-02-04T22:44:30.652Z)

Moment - toISOString()
Carbon - toIso8601ZuluString()
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы